12f18b292ff155af7df35930474857b507dbf18feTony Barbour/* 22f18b292ff155af7df35930474857b507dbf18feTony Barbour * Copyright (C) 2016 Google, Inc. 32f18b292ff155af7df35930474857b507dbf18feTony Barbour * 443b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * Licensed under the Apache License, Version 2.0 (the "License"); 543b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * you may not use this file except in compliance with the License. 643b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * You may obtain a copy of the License at 72f18b292ff155af7df35930474857b507dbf18feTony Barbour * 843b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * http://www.apache.org/licenses/LICENSE-2.0 92f18b292ff155af7df35930474857b507dbf18feTony Barbour * 1043b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * Unless required by applicable law or agreed to in writing, software 1143b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * distributed under the License is distributed on an "AS IS" BASIS, 1243b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1343b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * See the License for the specific language governing permissions and 1443b53e83705f02245da6ae61e31273866a35b833Jon Ashburn * limitations under the License. 152f18b292ff155af7df35930474857b507dbf18feTony Barbour */ 162f18b292ff155af7df35930474857b507dbf18feTony Barbour 172f18b292ff155af7df35930474857b507dbf18feTony Barbour#include <array> 182f18b292ff155af7df35930474857b507dbf18feTony Barbour 192f18b292ff155af7df35930474857b507dbf18feTony Barbour#include <glm/gtc/type_ptr.hpp> 202f18b292ff155af7df35930474857b507dbf18feTony Barbour#include <glm/gtc/matrix_transform.hpp> 212f18b292ff155af7df35930474857b507dbf18feTony Barbour 222f18b292ff155af7df35930474857b507dbf18feTony Barbour#include "Helpers.h" 232f18b292ff155af7df35930474857b507dbf18feTony Barbour#include "Smoke.h" 242f18b292ff155af7df35930474857b507dbf18feTony Barbour#include "Meshes.h" 252f18b292ff155af7df35930474857b507dbf18feTony Barbour#include "Shell.h" 262f18b292ff155af7df35930474857b507dbf18feTony Barbour 272f18b292ff155af7df35930474857b507dbf18feTony Barbournamespace { 282f18b292ff155af7df35930474857b507dbf18feTony Barbour 292f18b292ff155af7df35930474857b507dbf18feTony Barbour// TODO do not rely on compiler to use std140 layout 302f18b292ff155af7df35930474857b507dbf18feTony Barbour// TODO move lower frequency data to another descriptor set 312f18b292ff155af7df35930474857b507dbf18feTony Barbourstruct ShaderParamBlock { 322f18b292ff155af7df35930474857b507dbf18feTony Barbour float light_pos[4]; 332f18b292ff155af7df35930474857b507dbf18feTony Barbour float light_color[4]; 342f18b292ff155af7df35930474857b507dbf18feTony Barbour float model[4 * 4]; 352f18b292ff155af7df35930474857b507dbf18feTony Barbour float view_projection[4 * 4]; 362f18b292ff155af7df35930474857b507dbf18feTony Barbour}; 372f18b292ff155af7df35930474857b507dbf18feTony Barbour 382f18b292ff155af7df35930474857b507dbf18feTony Barbour} // namespace 392f18b292ff155af7df35930474857b507dbf18feTony Barbour 402f18b292ff155af7df35930474857b507dbf18feTony BarbourSmoke::Smoke(const std::vector<std::string> &args) 412f18b292ff155af7df35930474857b507dbf18feTony Barbour : Game("Smoke", args), multithread_(true), use_push_constants_(false), 422f18b292ff155af7df35930474857b507dbf18feTony Barbour sim_paused_(false), sim_(5000), camera_(2.5f), frame_data_(), 432f18b292ff155af7df35930474857b507dbf18feTony Barbour render_pass_clear_value_({{ 0.0f, 0.1f, 0.2f, 1.0f }}), 442f18b292ff155af7df35930474857b507dbf18feTony Barbour render_pass_begin_info_(), 452f18b292ff155af7df35930474857b507dbf18feTony Barbour primary_cmd_begin_info_(), primary_cmd_submit_info_() 462f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 472f18b292ff155af7df35930474857b507dbf18feTony Barbour for (auto it = args.begin(); it != args.end(); ++it) { 482f18b292ff155af7df35930474857b507dbf18feTony Barbour if (*it == "-s") 492f18b292ff155af7df35930474857b507dbf18feTony Barbour multithread_ = false; 502f18b292ff155af7df35930474857b507dbf18feTony Barbour else if (*it == "-p") 512f18b292ff155af7df35930474857b507dbf18feTony Barbour use_push_constants_ = true; 522f18b292ff155af7df35930474857b507dbf18feTony Barbour } 532f18b292ff155af7df35930474857b507dbf18feTony Barbour 542f18b292ff155af7df35930474857b507dbf18feTony Barbour init_workers(); 552f18b292ff155af7df35930474857b507dbf18feTony Barbour} 562f18b292ff155af7df35930474857b507dbf18feTony Barbour 572f18b292ff155af7df35930474857b507dbf18feTony BarbourSmoke::~Smoke() 582f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 592f18b292ff155af7df35930474857b507dbf18feTony Barbour} 602f18b292ff155af7df35930474857b507dbf18feTony Barbour 612f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::init_workers() 622f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 632f18b292ff155af7df35930474857b507dbf18feTony Barbour int worker_count = std::thread::hardware_concurrency(); 642f18b292ff155af7df35930474857b507dbf18feTony Barbour 652f18b292ff155af7df35930474857b507dbf18feTony Barbour // not enough cores 662f18b292ff155af7df35930474857b507dbf18feTony Barbour if (!multithread_ || worker_count < 2) { 672f18b292ff155af7df35930474857b507dbf18feTony Barbour multithread_ = false; 682f18b292ff155af7df35930474857b507dbf18feTony Barbour worker_count = 1; 692f18b292ff155af7df35930474857b507dbf18feTony Barbour } 702f18b292ff155af7df35930474857b507dbf18feTony Barbour 7120f5fc0adf53b1f48373ce4e40c745b0d67ebe44Dustin Graves const int object_per_worker = 7220f5fc0adf53b1f48373ce4e40c745b0d67ebe44Dustin Graves static_cast<int>(sim_.objects().size()) / worker_count; 732f18b292ff155af7df35930474857b507dbf18feTony Barbour int object_begin = 0, object_end = 0; 742f18b292ff155af7df35930474857b507dbf18feTony Barbour 752f18b292ff155af7df35930474857b507dbf18feTony Barbour workers_.reserve(worker_count); 762f18b292ff155af7df35930474857b507dbf18feTony Barbour for (int i = 0; i < worker_count; i++) { 772f18b292ff155af7df35930474857b507dbf18feTony Barbour object_begin = object_end; 782f18b292ff155af7df35930474857b507dbf18feTony Barbour if (i < worker_count - 1) 792f18b292ff155af7df35930474857b507dbf18feTony Barbour object_end += object_per_worker; 802f18b292ff155af7df35930474857b507dbf18feTony Barbour else 8120f5fc0adf53b1f48373ce4e40c745b0d67ebe44Dustin Graves object_end = static_cast<int>(sim_.objects().size()); 822f18b292ff155af7df35930474857b507dbf18feTony Barbour 832f18b292ff155af7df35930474857b507dbf18feTony Barbour Worker *worker = new Worker(*this, i, object_begin, object_end); 842f18b292ff155af7df35930474857b507dbf18feTony Barbour workers_.emplace_back(std::unique_ptr<Worker>(worker)); 852f18b292ff155af7df35930474857b507dbf18feTony Barbour } 862f18b292ff155af7df35930474857b507dbf18feTony Barbour} 872f18b292ff155af7df35930474857b507dbf18feTony Barbour 882f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::attach_shell(Shell &sh) 892f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 902f18b292ff155af7df35930474857b507dbf18feTony Barbour Game::attach_shell(sh); 912f18b292ff155af7df35930474857b507dbf18feTony Barbour 922f18b292ff155af7df35930474857b507dbf18feTony Barbour const Shell::Context &ctx = sh.context(); 932f18b292ff155af7df35930474857b507dbf18feTony Barbour physical_dev_ = ctx.physical_dev; 942f18b292ff155af7df35930474857b507dbf18feTony Barbour dev_ = ctx.dev; 952f18b292ff155af7df35930474857b507dbf18feTony Barbour queue_ = ctx.game_queue; 962f18b292ff155af7df35930474857b507dbf18feTony Barbour queue_family_ = ctx.game_queue_family; 972f18b292ff155af7df35930474857b507dbf18feTony Barbour format_ = ctx.format.format; 982f18b292ff155af7df35930474857b507dbf18feTony Barbour 992f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::GetPhysicalDeviceProperties(physical_dev_, &physical_dev_props_); 1002f18b292ff155af7df35930474857b507dbf18feTony Barbour 1012f18b292ff155af7df35930474857b507dbf18feTony Barbour if (use_push_constants_ && 1022f18b292ff155af7df35930474857b507dbf18feTony Barbour sizeof(ShaderParamBlock) > physical_dev_props_.limits.maxPushConstantsSize) { 1032f18b292ff155af7df35930474857b507dbf18feTony Barbour shell_->log(Shell::LOG_WARN, "cannot enable push constants"); 1042f18b292ff155af7df35930474857b507dbf18feTony Barbour use_push_constants_ = false; 1052f18b292ff155af7df35930474857b507dbf18feTony Barbour } 1062f18b292ff155af7df35930474857b507dbf18feTony Barbour 1072f18b292ff155af7df35930474857b507dbf18feTony Barbour VkPhysicalDeviceMemoryProperties mem_props; 1082f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::GetPhysicalDeviceMemoryProperties(physical_dev_, &mem_props); 1092f18b292ff155af7df35930474857b507dbf18feTony Barbour mem_flags_.reserve(mem_props.memoryTypeCount); 1102f18b292ff155af7df35930474857b507dbf18feTony Barbour for (uint32_t i = 0; i < mem_props.memoryTypeCount; i++) 1112f18b292ff155af7df35930474857b507dbf18feTony Barbour mem_flags_.push_back(mem_props.memoryTypes[i].propertyFlags); 1122f18b292ff155af7df35930474857b507dbf18feTony Barbour 1132f18b292ff155af7df35930474857b507dbf18feTony Barbour meshes_ = new Meshes(dev_, mem_flags_); 1142f18b292ff155af7df35930474857b507dbf18feTony Barbour 1152f18b292ff155af7df35930474857b507dbf18feTony Barbour create_render_pass(); 1162f18b292ff155af7df35930474857b507dbf18feTony Barbour create_shader_modules(); 1172f18b292ff155af7df35930474857b507dbf18feTony Barbour create_descriptor_set_layout(); 1182f18b292ff155af7df35930474857b507dbf18feTony Barbour create_pipeline_layout(); 1192f18b292ff155af7df35930474857b507dbf18feTony Barbour create_pipeline(); 1202f18b292ff155af7df35930474857b507dbf18feTony Barbour 1212f18b292ff155af7df35930474857b507dbf18feTony Barbour create_frame_data(2); 1222f18b292ff155af7df35930474857b507dbf18feTony Barbour 1232f18b292ff155af7df35930474857b507dbf18feTony Barbour render_pass_begin_info_.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; 1242f18b292ff155af7df35930474857b507dbf18feTony Barbour render_pass_begin_info_.renderPass = render_pass_; 1252f18b292ff155af7df35930474857b507dbf18feTony Barbour render_pass_begin_info_.clearValueCount = 1; 1262f18b292ff155af7df35930474857b507dbf18feTony Barbour render_pass_begin_info_.pClearValues = &render_pass_clear_value_; 1272f18b292ff155af7df35930474857b507dbf18feTony Barbour 1282f18b292ff155af7df35930474857b507dbf18feTony Barbour primary_cmd_begin_info_.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 1292f18b292ff155af7df35930474857b507dbf18feTony Barbour primary_cmd_begin_info_.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; 1302f18b292ff155af7df35930474857b507dbf18feTony Barbour 1312f18b292ff155af7df35930474857b507dbf18feTony Barbour // we will render to the swapchain images 1322f18b292ff155af7df35930474857b507dbf18feTony Barbour primary_cmd_submit_wait_stages_ = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; 1332f18b292ff155af7df35930474857b507dbf18feTony Barbour 1342f18b292ff155af7df35930474857b507dbf18feTony Barbour primary_cmd_submit_info_.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 1352f18b292ff155af7df35930474857b507dbf18feTony Barbour primary_cmd_submit_info_.waitSemaphoreCount = 1; 1362f18b292ff155af7df35930474857b507dbf18feTony Barbour primary_cmd_submit_info_.pWaitDstStageMask = &primary_cmd_submit_wait_stages_; 1372f18b292ff155af7df35930474857b507dbf18feTony Barbour primary_cmd_submit_info_.commandBufferCount = 1; 1382f18b292ff155af7df35930474857b507dbf18feTony Barbour primary_cmd_submit_info_.signalSemaphoreCount = 1; 1392f18b292ff155af7df35930474857b507dbf18feTony Barbour 1402f18b292ff155af7df35930474857b507dbf18feTony Barbour if (multithread_) { 1412f18b292ff155af7df35930474857b507dbf18feTony Barbour for (auto &worker : workers_) 1422f18b292ff155af7df35930474857b507dbf18feTony Barbour worker->start(); 1432f18b292ff155af7df35930474857b507dbf18feTony Barbour } 1442f18b292ff155af7df35930474857b507dbf18feTony Barbour} 1452f18b292ff155af7df35930474857b507dbf18feTony Barbour 1462f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::detach_shell() 1472f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 1482f18b292ff155af7df35930474857b507dbf18feTony Barbour if (multithread_) { 1492f18b292ff155af7df35930474857b507dbf18feTony Barbour for (auto &worker : workers_) 1502f18b292ff155af7df35930474857b507dbf18feTony Barbour worker->stop(); 1512f18b292ff155af7df35930474857b507dbf18feTony Barbour } 1522f18b292ff155af7df35930474857b507dbf18feTony Barbour 1532f18b292ff155af7df35930474857b507dbf18feTony Barbour destroy_frame_data(); 1542f18b292ff155af7df35930474857b507dbf18feTony Barbour 1552f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::DestroyPipeline(dev_, pipeline_, nullptr); 1562f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::DestroyPipelineLayout(dev_, pipeline_layout_, nullptr); 1572f18b292ff155af7df35930474857b507dbf18feTony Barbour if (!use_push_constants_) 1582f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::DestroyDescriptorSetLayout(dev_, desc_set_layout_, nullptr); 1592f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::DestroyShaderModule(dev_, fs_, nullptr); 1602f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::DestroyShaderModule(dev_, vs_, nullptr); 1612f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::DestroyRenderPass(dev_, render_pass_, nullptr); 1622f18b292ff155af7df35930474857b507dbf18feTony Barbour 1632f18b292ff155af7df35930474857b507dbf18feTony Barbour delete meshes_; 1642f18b292ff155af7df35930474857b507dbf18feTony Barbour 1652f18b292ff155af7df35930474857b507dbf18feTony Barbour Game::detach_shell(); 1662f18b292ff155af7df35930474857b507dbf18feTony Barbour} 1672f18b292ff155af7df35930474857b507dbf18feTony Barbour 1682f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::create_render_pass() 1692f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 1702f18b292ff155af7df35930474857b507dbf18feTony Barbour VkAttachmentDescription attachment = {}; 1712f18b292ff155af7df35930474857b507dbf18feTony Barbour attachment.format = format_; 1722f18b292ff155af7df35930474857b507dbf18feTony Barbour attachment.samples = VK_SAMPLE_COUNT_1_BIT; 1732f18b292ff155af7df35930474857b507dbf18feTony Barbour attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 1742f18b292ff155af7df35930474857b507dbf18feTony Barbour attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 1752f18b292ff155af7df35930474857b507dbf18feTony Barbour attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 1762f18b292ff155af7df35930474857b507dbf18feTony Barbour attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; 1772f18b292ff155af7df35930474857b507dbf18feTony Barbour 1782f18b292ff155af7df35930474857b507dbf18feTony Barbour VkAttachmentReference attachment_ref = {}; 1792f18b292ff155af7df35930474857b507dbf18feTony Barbour attachment_ref.attachment = 0; 1802f18b292ff155af7df35930474857b507dbf18feTony Barbour attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 1812f18b292ff155af7df35930474857b507dbf18feTony Barbour 1822f18b292ff155af7df35930474857b507dbf18feTony Barbour VkSubpassDescription subpass = {}; 1832f18b292ff155af7df35930474857b507dbf18feTony Barbour subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; 1842f18b292ff155af7df35930474857b507dbf18feTony Barbour subpass.colorAttachmentCount = 1; 1852f18b292ff155af7df35930474857b507dbf18feTony Barbour subpass.pColorAttachments = &attachment_ref; 1862f18b292ff155af7df35930474857b507dbf18feTony Barbour 1872f18b292ff155af7df35930474857b507dbf18feTony Barbour std::array<VkSubpassDependency, 2> subpass_deps; 1882f18b292ff155af7df35930474857b507dbf18feTony Barbour subpass_deps[0].srcSubpass = VK_SUBPASS_EXTERNAL; 1892f18b292ff155af7df35930474857b507dbf18feTony Barbour subpass_deps[0].dstSubpass = 0; 1902f18b292ff155af7df35930474857b507dbf18feTony Barbour subpass_deps[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; 1912f18b292ff155af7df35930474857b507dbf18feTony Barbour subpass_deps[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; 1922f18b292ff155af7df35930474857b507dbf18feTony Barbour subpass_deps[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT; 1932f18b292ff155af7df35930474857b507dbf18feTony Barbour subpass_deps[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | 1942f18b292ff155af7df35930474857b507dbf18feTony Barbour VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 1952f18b292ff155af7df35930474857b507dbf18feTony Barbour subpass_deps[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; 1962f18b292ff155af7df35930474857b507dbf18feTony Barbour 1972f18b292ff155af7df35930474857b507dbf18feTony Barbour subpass_deps[1].srcSubpass = 0; 1982f18b292ff155af7df35930474857b507dbf18feTony Barbour subpass_deps[1].dstSubpass = VK_SUBPASS_EXTERNAL; 1992f18b292ff155af7df35930474857b507dbf18feTony Barbour subpass_deps[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; 2002f18b292ff155af7df35930474857b507dbf18feTony Barbour subpass_deps[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; 2012f18b292ff155af7df35930474857b507dbf18feTony Barbour subpass_deps[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | 2022f18b292ff155af7df35930474857b507dbf18feTony Barbour VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 2032f18b292ff155af7df35930474857b507dbf18feTony Barbour subpass_deps[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; 2042f18b292ff155af7df35930474857b507dbf18feTony Barbour subpass_deps[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; 2052f18b292ff155af7df35930474857b507dbf18feTony Barbour 2062f18b292ff155af7df35930474857b507dbf18feTony Barbour VkRenderPassCreateInfo render_pass_info = {}; 2072f18b292ff155af7df35930474857b507dbf18feTony Barbour render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 2082f18b292ff155af7df35930474857b507dbf18feTony Barbour render_pass_info.attachmentCount = 1; 2092f18b292ff155af7df35930474857b507dbf18feTony Barbour render_pass_info.pAttachments = &attachment; 2102f18b292ff155af7df35930474857b507dbf18feTony Barbour render_pass_info.subpassCount = 1; 2112f18b292ff155af7df35930474857b507dbf18feTony Barbour render_pass_info.pSubpasses = &subpass; 2122f18b292ff155af7df35930474857b507dbf18feTony Barbour render_pass_info.dependencyCount = (uint32_t)subpass_deps.size(); 2132f18b292ff155af7df35930474857b507dbf18feTony Barbour render_pass_info.pDependencies = subpass_deps.data(); 2142f18b292ff155af7df35930474857b507dbf18feTony Barbour 2152f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::assert_success(vk::CreateRenderPass(dev_, &render_pass_info, nullptr, &render_pass_)); 2162f18b292ff155af7df35930474857b507dbf18feTony Barbour} 2172f18b292ff155af7df35930474857b507dbf18feTony Barbour 2182f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::create_shader_modules() 2192f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 2202f18b292ff155af7df35930474857b507dbf18feTony Barbour VkShaderModuleCreateInfo sh_info = {}; 2212f18b292ff155af7df35930474857b507dbf18feTony Barbour sh_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; 2222f18b292ff155af7df35930474857b507dbf18feTony Barbour if (use_push_constants_) { 2232f18b292ff155af7df35930474857b507dbf18feTony Barbour#include "Smoke.push_constant.vert.h" 2242f18b292ff155af7df35930474857b507dbf18feTony Barbour sh_info.codeSize = sizeof(Smoke_push_constant_vert); 2252f18b292ff155af7df35930474857b507dbf18feTony Barbour sh_info.pCode = Smoke_push_constant_vert; 2262f18b292ff155af7df35930474857b507dbf18feTony Barbour } else { 2272f18b292ff155af7df35930474857b507dbf18feTony Barbour#include "Smoke.vert.h" 2282f18b292ff155af7df35930474857b507dbf18feTony Barbour sh_info.codeSize = sizeof(Smoke_vert); 2292f18b292ff155af7df35930474857b507dbf18feTony Barbour sh_info.pCode = Smoke_vert; 2302f18b292ff155af7df35930474857b507dbf18feTony Barbour } 2312f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::assert_success(vk::CreateShaderModule(dev_, &sh_info, nullptr, &vs_)); 2322f18b292ff155af7df35930474857b507dbf18feTony Barbour 2332f18b292ff155af7df35930474857b507dbf18feTony Barbour#include "Smoke.frag.h" 2342f18b292ff155af7df35930474857b507dbf18feTony Barbour sh_info.codeSize = sizeof(Smoke_frag); 2352f18b292ff155af7df35930474857b507dbf18feTony Barbour sh_info.pCode = Smoke_frag; 2362f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::assert_success(vk::CreateShaderModule(dev_, &sh_info, nullptr, &fs_)); 2372f18b292ff155af7df35930474857b507dbf18feTony Barbour} 2382f18b292ff155af7df35930474857b507dbf18feTony Barbour 2392f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::create_descriptor_set_layout() 2402f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 2412f18b292ff155af7df35930474857b507dbf18feTony Barbour if (use_push_constants_) 2422f18b292ff155af7df35930474857b507dbf18feTony Barbour return; 2432f18b292ff155af7df35930474857b507dbf18feTony Barbour 2442f18b292ff155af7df35930474857b507dbf18feTony Barbour VkDescriptorSetLayoutBinding layout_binding = {}; 2452f18b292ff155af7df35930474857b507dbf18feTony Barbour layout_binding.binding = 0; 2462f18b292ff155af7df35930474857b507dbf18feTony Barbour layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; 2472f18b292ff155af7df35930474857b507dbf18feTony Barbour layout_binding.descriptorCount = 1; 2482f18b292ff155af7df35930474857b507dbf18feTony Barbour layout_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; 2492f18b292ff155af7df35930474857b507dbf18feTony Barbour 2502f18b292ff155af7df35930474857b507dbf18feTony Barbour VkDescriptorSetLayoutCreateInfo layout_info = {}; 2512f18b292ff155af7df35930474857b507dbf18feTony Barbour layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 2522f18b292ff155af7df35930474857b507dbf18feTony Barbour layout_info.bindingCount = 1; 2532f18b292ff155af7df35930474857b507dbf18feTony Barbour layout_info.pBindings = &layout_binding; 2542f18b292ff155af7df35930474857b507dbf18feTony Barbour 2552f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::assert_success(vk::CreateDescriptorSetLayout(dev_, &layout_info, 2562f18b292ff155af7df35930474857b507dbf18feTony Barbour nullptr, &desc_set_layout_)); 2572f18b292ff155af7df35930474857b507dbf18feTony Barbour} 2582f18b292ff155af7df35930474857b507dbf18feTony Barbour 2592f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::create_pipeline_layout() 2602f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 2612f18b292ff155af7df35930474857b507dbf18feTony Barbour VkPushConstantRange push_const_range = {}; 2622f18b292ff155af7df35930474857b507dbf18feTony Barbour 2632f18b292ff155af7df35930474857b507dbf18feTony Barbour VkPipelineLayoutCreateInfo pipeline_layout_info = {}; 2642f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 2652f18b292ff155af7df35930474857b507dbf18feTony Barbour 2662f18b292ff155af7df35930474857b507dbf18feTony Barbour if (use_push_constants_) { 2672f18b292ff155af7df35930474857b507dbf18feTony Barbour push_const_range.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; 2682f18b292ff155af7df35930474857b507dbf18feTony Barbour push_const_range.offset = 0; 2692f18b292ff155af7df35930474857b507dbf18feTony Barbour push_const_range.size = sizeof(ShaderParamBlock); 2702f18b292ff155af7df35930474857b507dbf18feTony Barbour 2712f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_layout_info.pushConstantRangeCount = 1; 2722f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_layout_info.pPushConstantRanges = &push_const_range; 2732f18b292ff155af7df35930474857b507dbf18feTony Barbour } else { 2742f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_layout_info.setLayoutCount = 1; 2752f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_layout_info.pSetLayouts = &desc_set_layout_; 2762f18b292ff155af7df35930474857b507dbf18feTony Barbour } 2772f18b292ff155af7df35930474857b507dbf18feTony Barbour 2782f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::assert_success(vk::CreatePipelineLayout(dev_, &pipeline_layout_info, 2792f18b292ff155af7df35930474857b507dbf18feTony Barbour nullptr, &pipeline_layout_)); 2802f18b292ff155af7df35930474857b507dbf18feTony Barbour} 2812f18b292ff155af7df35930474857b507dbf18feTony Barbour 2822f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::create_pipeline() 2832f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 2842f18b292ff155af7df35930474857b507dbf18feTony Barbour VkPipelineShaderStageCreateInfo stage_info[2] = {}; 2852f18b292ff155af7df35930474857b507dbf18feTony Barbour stage_info[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 2862f18b292ff155af7df35930474857b507dbf18feTony Barbour stage_info[0].stage = VK_SHADER_STAGE_VERTEX_BIT; 2872f18b292ff155af7df35930474857b507dbf18feTony Barbour stage_info[0].module = vs_; 2882f18b292ff155af7df35930474857b507dbf18feTony Barbour stage_info[0].pName = "main"; 2892f18b292ff155af7df35930474857b507dbf18feTony Barbour stage_info[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 2902f18b292ff155af7df35930474857b507dbf18feTony Barbour stage_info[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; 2912f18b292ff155af7df35930474857b507dbf18feTony Barbour stage_info[1].module = fs_; 2922f18b292ff155af7df35930474857b507dbf18feTony Barbour stage_info[1].pName = "main"; 2932f18b292ff155af7df35930474857b507dbf18feTony Barbour 2942f18b292ff155af7df35930474857b507dbf18feTony Barbour VkPipelineViewportStateCreateInfo viewport_info = {}; 2952f18b292ff155af7df35930474857b507dbf18feTony Barbour viewport_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 2962f18b292ff155af7df35930474857b507dbf18feTony Barbour // both dynamic 2972f18b292ff155af7df35930474857b507dbf18feTony Barbour viewport_info.viewportCount = 1; 2982f18b292ff155af7df35930474857b507dbf18feTony Barbour viewport_info.scissorCount = 1; 2992f18b292ff155af7df35930474857b507dbf18feTony Barbour 3002f18b292ff155af7df35930474857b507dbf18feTony Barbour VkPipelineRasterizationStateCreateInfo rast_info = {}; 3012f18b292ff155af7df35930474857b507dbf18feTony Barbour rast_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 3022f18b292ff155af7df35930474857b507dbf18feTony Barbour rast_info.depthClampEnable = false; 3032f18b292ff155af7df35930474857b507dbf18feTony Barbour rast_info.rasterizerDiscardEnable = false; 3042f18b292ff155af7df35930474857b507dbf18feTony Barbour rast_info.polygonMode = VK_POLYGON_MODE_FILL; 3052f18b292ff155af7df35930474857b507dbf18feTony Barbour rast_info.cullMode = VK_CULL_MODE_NONE; 3062f18b292ff155af7df35930474857b507dbf18feTony Barbour rast_info.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; 3072f18b292ff155af7df35930474857b507dbf18feTony Barbour rast_info.depthBiasEnable = false; 3082f18b292ff155af7df35930474857b507dbf18feTony Barbour rast_info.lineWidth = 1.0f; 3092f18b292ff155af7df35930474857b507dbf18feTony Barbour 3102f18b292ff155af7df35930474857b507dbf18feTony Barbour VkPipelineMultisampleStateCreateInfo multisample_info = {}; 3112f18b292ff155af7df35930474857b507dbf18feTony Barbour multisample_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 3122f18b292ff155af7df35930474857b507dbf18feTony Barbour multisample_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 3132f18b292ff155af7df35930474857b507dbf18feTony Barbour multisample_info.sampleShadingEnable = false; 3142f18b292ff155af7df35930474857b507dbf18feTony Barbour multisample_info.pSampleMask = nullptr; 3152f18b292ff155af7df35930474857b507dbf18feTony Barbour multisample_info.alphaToCoverageEnable = false; 3162f18b292ff155af7df35930474857b507dbf18feTony Barbour multisample_info.alphaToOneEnable = false; 3172f18b292ff155af7df35930474857b507dbf18feTony Barbour 3182f18b292ff155af7df35930474857b507dbf18feTony Barbour VkPipelineColorBlendAttachmentState blend_attachment = {}; 3192f18b292ff155af7df35930474857b507dbf18feTony Barbour blend_attachment.blendEnable = true; 3202f18b292ff155af7df35930474857b507dbf18feTony Barbour blend_attachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; 3212f18b292ff155af7df35930474857b507dbf18feTony Barbour blend_attachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; 3222f18b292ff155af7df35930474857b507dbf18feTony Barbour blend_attachment.colorBlendOp = VK_BLEND_OP_ADD; 3232f18b292ff155af7df35930474857b507dbf18feTony Barbour blend_attachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; 3242f18b292ff155af7df35930474857b507dbf18feTony Barbour blend_attachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; 3252f18b292ff155af7df35930474857b507dbf18feTony Barbour blend_attachment.alphaBlendOp = VK_BLEND_OP_ADD; 3262f18b292ff155af7df35930474857b507dbf18feTony Barbour blend_attachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | 3272f18b292ff155af7df35930474857b507dbf18feTony Barbour VK_COLOR_COMPONENT_G_BIT | 3282f18b292ff155af7df35930474857b507dbf18feTony Barbour VK_COLOR_COMPONENT_B_BIT | 3292f18b292ff155af7df35930474857b507dbf18feTony Barbour VK_COLOR_COMPONENT_A_BIT; 3302f18b292ff155af7df35930474857b507dbf18feTony Barbour 3312f18b292ff155af7df35930474857b507dbf18feTony Barbour VkPipelineColorBlendStateCreateInfo blend_info = {}; 3322f18b292ff155af7df35930474857b507dbf18feTony Barbour blend_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 3332f18b292ff155af7df35930474857b507dbf18feTony Barbour blend_info.logicOpEnable = false; 3342f18b292ff155af7df35930474857b507dbf18feTony Barbour blend_info.attachmentCount = 1; 3352f18b292ff155af7df35930474857b507dbf18feTony Barbour blend_info.pAttachments = &blend_attachment; 3362f18b292ff155af7df35930474857b507dbf18feTony Barbour 3372f18b292ff155af7df35930474857b507dbf18feTony Barbour std::array<VkDynamicState, 2> dynamic_states = { 3382f18b292ff155af7df35930474857b507dbf18feTony Barbour VK_DYNAMIC_STATE_VIEWPORT, 3392f18b292ff155af7df35930474857b507dbf18feTony Barbour VK_DYNAMIC_STATE_SCISSOR 3402f18b292ff155af7df35930474857b507dbf18feTony Barbour }; 3412f18b292ff155af7df35930474857b507dbf18feTony Barbour struct VkPipelineDynamicStateCreateInfo dynamic_info = {}; 3422f18b292ff155af7df35930474857b507dbf18feTony Barbour dynamic_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; 3432f18b292ff155af7df35930474857b507dbf18feTony Barbour dynamic_info.dynamicStateCount = (uint32_t)dynamic_states.size(); 3442f18b292ff155af7df35930474857b507dbf18feTony Barbour dynamic_info.pDynamicStates = dynamic_states.data(); 3452f18b292ff155af7df35930474857b507dbf18feTony Barbour 3462f18b292ff155af7df35930474857b507dbf18feTony Barbour VkGraphicsPipelineCreateInfo pipeline_info = {}; 3472f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 3482f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_info.stageCount = 2; 3492f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_info.pStages = stage_info; 3502f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_info.pVertexInputState = &meshes_->vertex_input_state(); 3512f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_info.pInputAssemblyState = &meshes_->input_assembly_state(); 3522f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_info.pTessellationState = nullptr; 3532f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_info.pViewportState = &viewport_info; 3542f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_info.pRasterizationState = &rast_info; 3552f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_info.pMultisampleState = &multisample_info; 3562f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_info.pDepthStencilState = nullptr; 3572f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_info.pColorBlendState = &blend_info; 3582f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_info.pDynamicState = &dynamic_info; 3592f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_info.layout = pipeline_layout_; 3602f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_info.renderPass = render_pass_; 3612f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_info.subpass = 0; 3622f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::assert_success(vk::CreateGraphicsPipelines(dev_, VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &pipeline_)); 3632f18b292ff155af7df35930474857b507dbf18feTony Barbour} 3642f18b292ff155af7df35930474857b507dbf18feTony Barbour 3652f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::create_frame_data(int count) 3662f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 3672f18b292ff155af7df35930474857b507dbf18feTony Barbour frame_data_.resize(count); 3682f18b292ff155af7df35930474857b507dbf18feTony Barbour 3692f18b292ff155af7df35930474857b507dbf18feTony Barbour create_fences(); 3702f18b292ff155af7df35930474857b507dbf18feTony Barbour create_command_buffers(); 3712f18b292ff155af7df35930474857b507dbf18feTony Barbour 3722f18b292ff155af7df35930474857b507dbf18feTony Barbour if (!use_push_constants_) { 3732f18b292ff155af7df35930474857b507dbf18feTony Barbour create_buffers(); 3742f18b292ff155af7df35930474857b507dbf18feTony Barbour create_buffer_memory(); 3752f18b292ff155af7df35930474857b507dbf18feTony Barbour create_descriptor_sets(); 3762f18b292ff155af7df35930474857b507dbf18feTony Barbour } 3772f18b292ff155af7df35930474857b507dbf18feTony Barbour 3782f18b292ff155af7df35930474857b507dbf18feTony Barbour frame_data_index_ = 0; 3792f18b292ff155af7df35930474857b507dbf18feTony Barbour} 3802f18b292ff155af7df35930474857b507dbf18feTony Barbour 3812f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::destroy_frame_data() 3822f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 3832f18b292ff155af7df35930474857b507dbf18feTony Barbour if (!use_push_constants_) { 3842f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::DestroyDescriptorPool(dev_, desc_pool_, nullptr); 3852f18b292ff155af7df35930474857b507dbf18feTony Barbour 3862f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::UnmapMemory(dev_, frame_data_mem_); 3872f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::FreeMemory(dev_, frame_data_mem_, nullptr); 3882f18b292ff155af7df35930474857b507dbf18feTony Barbour 3892f18b292ff155af7df35930474857b507dbf18feTony Barbour for (auto &data : frame_data_) 3902f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::DestroyBuffer(dev_, data.buf, nullptr); 3912f18b292ff155af7df35930474857b507dbf18feTony Barbour } 3922f18b292ff155af7df35930474857b507dbf18feTony Barbour 3935122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz for (auto cmd_pool : worker_cmd_pools_) 3945122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz vk::DestroyCommandPool(dev_, cmd_pool, nullptr); 3955122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz worker_cmd_pools_.clear(); 3965122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz vk::DestroyCommandPool(dev_, primary_cmd_pool_, nullptr); 3975122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz 3982f18b292ff155af7df35930474857b507dbf18feTony Barbour for (auto &data : frame_data_) 3992f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::DestroyFence(dev_, data.fence, nullptr); 4002f18b292ff155af7df35930474857b507dbf18feTony Barbour 4012f18b292ff155af7df35930474857b507dbf18feTony Barbour frame_data_.clear(); 4022f18b292ff155af7df35930474857b507dbf18feTony Barbour} 4032f18b292ff155af7df35930474857b507dbf18feTony Barbour 4042f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::create_fences() 4052f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 4062f18b292ff155af7df35930474857b507dbf18feTony Barbour VkFenceCreateInfo fence_info = {}; 4072f18b292ff155af7df35930474857b507dbf18feTony Barbour fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 4082f18b292ff155af7df35930474857b507dbf18feTony Barbour fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT; 4092f18b292ff155af7df35930474857b507dbf18feTony Barbour 4102f18b292ff155af7df35930474857b507dbf18feTony Barbour for (auto &data : frame_data_) 4112f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::assert_success(vk::CreateFence(dev_, &fence_info, nullptr, &data.fence)); 4122f18b292ff155af7df35930474857b507dbf18feTony Barbour} 4132f18b292ff155af7df35930474857b507dbf18feTony Barbour 4142f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::create_command_buffers() 4152f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 4162f18b292ff155af7df35930474857b507dbf18feTony Barbour VkCommandPoolCreateInfo cmd_pool_info = {}; 4172f18b292ff155af7df35930474857b507dbf18feTony Barbour cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 4182f18b292ff155af7df35930474857b507dbf18feTony Barbour cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 4192f18b292ff155af7df35930474857b507dbf18feTony Barbour cmd_pool_info.queueFamilyIndex = queue_family_; 4202f18b292ff155af7df35930474857b507dbf18feTony Barbour 4212f18b292ff155af7df35930474857b507dbf18feTony Barbour VkCommandBufferAllocateInfo cmd_info = {}; 4222f18b292ff155af7df35930474857b507dbf18feTony Barbour cmd_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 4232f18b292ff155af7df35930474857b507dbf18feTony Barbour cmd_info.commandBufferCount = static_cast<uint32_t>(frame_data_.size()); 4242f18b292ff155af7df35930474857b507dbf18feTony Barbour 4252f18b292ff155af7df35930474857b507dbf18feTony Barbour // create command pools and buffers 4262f18b292ff155af7df35930474857b507dbf18feTony Barbour std::vector<VkCommandPool> cmd_pools(workers_.size() + 1, VK_NULL_HANDLE); 4272f18b292ff155af7df35930474857b507dbf18feTony Barbour std::vector<std::vector<VkCommandBuffer>> cmds_vec(workers_.size() + 1, 4282f18b292ff155af7df35930474857b507dbf18feTony Barbour std::vector<VkCommandBuffer>(frame_data_.size(), VK_NULL_HANDLE)); 4292f18b292ff155af7df35930474857b507dbf18feTony Barbour for (size_t i = 0; i < cmd_pools.size(); i++) { 4302f18b292ff155af7df35930474857b507dbf18feTony Barbour auto &cmd_pool = cmd_pools[i]; 4312f18b292ff155af7df35930474857b507dbf18feTony Barbour auto &cmds = cmds_vec[i]; 4322f18b292ff155af7df35930474857b507dbf18feTony Barbour 4332f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::assert_success(vk::CreateCommandPool(dev_, &cmd_pool_info, 4342f18b292ff155af7df35930474857b507dbf18feTony Barbour nullptr, &cmd_pool)); 4352f18b292ff155af7df35930474857b507dbf18feTony Barbour 4362f18b292ff155af7df35930474857b507dbf18feTony Barbour cmd_info.commandPool = cmd_pool; 4372f18b292ff155af7df35930474857b507dbf18feTony Barbour cmd_info.level = (cmd_pool == cmd_pools.back()) ? 4382f18b292ff155af7df35930474857b507dbf18feTony Barbour VK_COMMAND_BUFFER_LEVEL_PRIMARY : VK_COMMAND_BUFFER_LEVEL_SECONDARY; 4392f18b292ff155af7df35930474857b507dbf18feTony Barbour 4402f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::assert_success(vk::AllocateCommandBuffers(dev_, &cmd_info, cmds.data())); 4412f18b292ff155af7df35930474857b507dbf18feTony Barbour } 4422f18b292ff155af7df35930474857b507dbf18feTony Barbour 4432f18b292ff155af7df35930474857b507dbf18feTony Barbour // update frame_data_ 4442f18b292ff155af7df35930474857b507dbf18feTony Barbour for (size_t i = 0; i < frame_data_.size(); i++) { 4452f18b292ff155af7df35930474857b507dbf18feTony Barbour for (const auto &cmds : cmds_vec) { 4462f18b292ff155af7df35930474857b507dbf18feTony Barbour if (cmds == cmds_vec.back()) { 4472f18b292ff155af7df35930474857b507dbf18feTony Barbour frame_data_[i].primary_cmd = cmds[i]; 4482f18b292ff155af7df35930474857b507dbf18feTony Barbour } else { 4492f18b292ff155af7df35930474857b507dbf18feTony Barbour frame_data_[i].worker_cmds.push_back(cmds[i]); 4502f18b292ff155af7df35930474857b507dbf18feTony Barbour } 4512f18b292ff155af7df35930474857b507dbf18feTony Barbour } 4522f18b292ff155af7df35930474857b507dbf18feTony Barbour } 4532f18b292ff155af7df35930474857b507dbf18feTony Barbour 4542f18b292ff155af7df35930474857b507dbf18feTony Barbour primary_cmd_pool_ = cmd_pools.back(); 4552f18b292ff155af7df35930474857b507dbf18feTony Barbour cmd_pools.pop_back(); 4562f18b292ff155af7df35930474857b507dbf18feTony Barbour worker_cmd_pools_ = cmd_pools; 4572f18b292ff155af7df35930474857b507dbf18feTony Barbour} 4582f18b292ff155af7df35930474857b507dbf18feTony Barbour 4592f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::create_buffers() 4602f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 4612f18b292ff155af7df35930474857b507dbf18feTony Barbour VkDeviceSize object_data_size = sizeof(ShaderParamBlock); 4622f18b292ff155af7df35930474857b507dbf18feTony Barbour // align object data to device limit 4632f18b292ff155af7df35930474857b507dbf18feTony Barbour const VkDeviceSize &alignment = 4642f18b292ff155af7df35930474857b507dbf18feTony Barbour physical_dev_props_.limits.minStorageBufferOffsetAlignment; 4652f18b292ff155af7df35930474857b507dbf18feTony Barbour if (object_data_size % alignment) 4662f18b292ff155af7df35930474857b507dbf18feTony Barbour object_data_size += alignment - (object_data_size % alignment); 4672f18b292ff155af7df35930474857b507dbf18feTony Barbour 4682f18b292ff155af7df35930474857b507dbf18feTony Barbour // update simulation 46920f5fc0adf53b1f48373ce4e40c745b0d67ebe44Dustin Graves sim_.set_frame_data_size(static_cast<uint32_t>(object_data_size)); 4702f18b292ff155af7df35930474857b507dbf18feTony Barbour 4712f18b292ff155af7df35930474857b507dbf18feTony Barbour VkBufferCreateInfo buf_info = {}; 4722f18b292ff155af7df35930474857b507dbf18feTony Barbour buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 4732f18b292ff155af7df35930474857b507dbf18feTony Barbour buf_info.size = object_data_size * sim_.objects().size(); 4742f18b292ff155af7df35930474857b507dbf18feTony Barbour buf_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; 4752f18b292ff155af7df35930474857b507dbf18feTony Barbour buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 4762f18b292ff155af7df35930474857b507dbf18feTony Barbour 4772f18b292ff155af7df35930474857b507dbf18feTony Barbour for (auto &data : frame_data_) 4782f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::assert_success(vk::CreateBuffer(dev_, &buf_info, nullptr, &data.buf)); 4792f18b292ff155af7df35930474857b507dbf18feTony Barbour} 4802f18b292ff155af7df35930474857b507dbf18feTony Barbour 4812f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::create_buffer_memory() 4822f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 4832f18b292ff155af7df35930474857b507dbf18feTony Barbour VkMemoryRequirements mem_reqs; 4842f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::GetBufferMemoryRequirements(dev_, frame_data_[0].buf, &mem_reqs); 4852f18b292ff155af7df35930474857b507dbf18feTony Barbour 4862f18b292ff155af7df35930474857b507dbf18feTony Barbour VkDeviceSize aligned_size = mem_reqs.size; 4872f18b292ff155af7df35930474857b507dbf18feTony Barbour if (aligned_size % mem_reqs.alignment) 4882f18b292ff155af7df35930474857b507dbf18feTony Barbour aligned_size += mem_reqs.alignment - (aligned_size % mem_reqs.alignment); 4892f18b292ff155af7df35930474857b507dbf18feTony Barbour 4902f18b292ff155af7df35930474857b507dbf18feTony Barbour // allocate memory 4912f18b292ff155af7df35930474857b507dbf18feTony Barbour VkMemoryAllocateInfo mem_info = {}; 4922f18b292ff155af7df35930474857b507dbf18feTony Barbour mem_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 4932f18b292ff155af7df35930474857b507dbf18feTony Barbour mem_info.allocationSize = aligned_size * (frame_data_.size() - 1) + 4942f18b292ff155af7df35930474857b507dbf18feTony Barbour mem_reqs.size; 4952f18b292ff155af7df35930474857b507dbf18feTony Barbour 4962f18b292ff155af7df35930474857b507dbf18feTony Barbour for (uint32_t idx = 0; idx < mem_flags_.size(); idx++) { 4972f18b292ff155af7df35930474857b507dbf18feTony Barbour if ((mem_reqs.memoryTypeBits & (1 << idx)) && 4982f18b292ff155af7df35930474857b507dbf18feTony Barbour (mem_flags_[idx] & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) && 4992f18b292ff155af7df35930474857b507dbf18feTony Barbour (mem_flags_[idx] & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) { 5002f18b292ff155af7df35930474857b507dbf18feTony Barbour // TODO is this guaranteed to exist? 5012f18b292ff155af7df35930474857b507dbf18feTony Barbour mem_info.memoryTypeIndex = idx; 5022f18b292ff155af7df35930474857b507dbf18feTony Barbour break; 5032f18b292ff155af7df35930474857b507dbf18feTony Barbour } 5042f18b292ff155af7df35930474857b507dbf18feTony Barbour } 5052f18b292ff155af7df35930474857b507dbf18feTony Barbour 5062f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::AllocateMemory(dev_, &mem_info, nullptr, &frame_data_mem_); 5072f18b292ff155af7df35930474857b507dbf18feTony Barbour 5082f18b292ff155af7df35930474857b507dbf18feTony Barbour void *ptr; 5092f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::MapMemory(dev_, frame_data_mem_, 0, VK_WHOLE_SIZE, 0, &ptr); 5102f18b292ff155af7df35930474857b507dbf18feTony Barbour 5112f18b292ff155af7df35930474857b507dbf18feTony Barbour VkDeviceSize offset = 0; 5122f18b292ff155af7df35930474857b507dbf18feTony Barbour for (auto &data : frame_data_) { 5132f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::BindBufferMemory(dev_, data.buf, frame_data_mem_, offset); 5142f18b292ff155af7df35930474857b507dbf18feTony Barbour data.base = reinterpret_cast<uint8_t *>(ptr) + offset; 5152f18b292ff155af7df35930474857b507dbf18feTony Barbour offset += aligned_size; 5162f18b292ff155af7df35930474857b507dbf18feTony Barbour } 5172f18b292ff155af7df35930474857b507dbf18feTony Barbour} 5182f18b292ff155af7df35930474857b507dbf18feTony Barbour 5192f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::create_descriptor_sets() 5202f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 5212f18b292ff155af7df35930474857b507dbf18feTony Barbour VkDescriptorPoolSize desc_pool_size = {}; 5222f18b292ff155af7df35930474857b507dbf18feTony Barbour desc_pool_size.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; 52320f5fc0adf53b1f48373ce4e40c745b0d67ebe44Dustin Graves desc_pool_size.descriptorCount = static_cast<uint32_t>(frame_data_.size()); 5242f18b292ff155af7df35930474857b507dbf18feTony Barbour 5252f18b292ff155af7df35930474857b507dbf18feTony Barbour VkDescriptorPoolCreateInfo desc_pool_info = {}; 5262f18b292ff155af7df35930474857b507dbf18feTony Barbour desc_pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 52720f5fc0adf53b1f48373ce4e40c745b0d67ebe44Dustin Graves desc_pool_info.maxSets = static_cast<uint32_t>(frame_data_.size()); 5282f18b292ff155af7df35930474857b507dbf18feTony Barbour desc_pool_info.poolSizeCount = 1; 5292f18b292ff155af7df35930474857b507dbf18feTony Barbour desc_pool_info.pPoolSizes = &desc_pool_size; 5302f18b292ff155af7df35930474857b507dbf18feTony Barbour 5312f18b292ff155af7df35930474857b507dbf18feTony Barbour // create descriptor pool 5322f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::assert_success(vk::CreateDescriptorPool(dev_, &desc_pool_info, 5332f18b292ff155af7df35930474857b507dbf18feTony Barbour nullptr, &desc_pool_)); 5342f18b292ff155af7df35930474857b507dbf18feTony Barbour 5352f18b292ff155af7df35930474857b507dbf18feTony Barbour std::vector<VkDescriptorSetLayout> set_layouts(frame_data_.size(), desc_set_layout_); 5362f18b292ff155af7df35930474857b507dbf18feTony Barbour VkDescriptorSetAllocateInfo set_info = {}; 5372f18b292ff155af7df35930474857b507dbf18feTony Barbour set_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 5382f18b292ff155af7df35930474857b507dbf18feTony Barbour set_info.descriptorPool = desc_pool_; 5392f18b292ff155af7df35930474857b507dbf18feTony Barbour set_info.descriptorSetCount = static_cast<uint32_t>(set_layouts.size()); 5402f18b292ff155af7df35930474857b507dbf18feTony Barbour set_info.pSetLayouts = set_layouts.data(); 5412f18b292ff155af7df35930474857b507dbf18feTony Barbour 5422f18b292ff155af7df35930474857b507dbf18feTony Barbour // create descriptor sets 5432f18b292ff155af7df35930474857b507dbf18feTony Barbour std::vector<VkDescriptorSet> desc_sets(frame_data_.size(), VK_NULL_HANDLE); 5442f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::assert_success(vk::AllocateDescriptorSets(dev_, &set_info, desc_sets.data())); 5452f18b292ff155af7df35930474857b507dbf18feTony Barbour 5462f18b292ff155af7df35930474857b507dbf18feTony Barbour std::vector<VkDescriptorBufferInfo> desc_bufs(frame_data_.size()); 5472f18b292ff155af7df35930474857b507dbf18feTony Barbour std::vector<VkWriteDescriptorSet> desc_writes(frame_data_.size()); 5482f18b292ff155af7df35930474857b507dbf18feTony Barbour 5492f18b292ff155af7df35930474857b507dbf18feTony Barbour for (size_t i = 0; i < frame_data_.size(); i++) { 5502f18b292ff155af7df35930474857b507dbf18feTony Barbour auto &data = frame_data_[i]; 5512f18b292ff155af7df35930474857b507dbf18feTony Barbour 5522f18b292ff155af7df35930474857b507dbf18feTony Barbour data.desc_set = desc_sets[i]; 5532f18b292ff155af7df35930474857b507dbf18feTony Barbour 5542f18b292ff155af7df35930474857b507dbf18feTony Barbour VkDescriptorBufferInfo desc_buf = {}; 5552f18b292ff155af7df35930474857b507dbf18feTony Barbour desc_buf.buffer = data.buf; 5562f18b292ff155af7df35930474857b507dbf18feTony Barbour desc_buf.offset = 0; 5572f18b292ff155af7df35930474857b507dbf18feTony Barbour desc_buf.range = VK_WHOLE_SIZE; 5582f18b292ff155af7df35930474857b507dbf18feTony Barbour desc_bufs[i] = desc_buf; 5592f18b292ff155af7df35930474857b507dbf18feTony Barbour 5602f18b292ff155af7df35930474857b507dbf18feTony Barbour VkWriteDescriptorSet desc_write = {}; 5612f18b292ff155af7df35930474857b507dbf18feTony Barbour desc_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 5622f18b292ff155af7df35930474857b507dbf18feTony Barbour desc_write.dstSet = data.desc_set; 5632f18b292ff155af7df35930474857b507dbf18feTony Barbour desc_write.dstBinding = 0; 5642f18b292ff155af7df35930474857b507dbf18feTony Barbour desc_write.dstArrayElement = 0; 5652f18b292ff155af7df35930474857b507dbf18feTony Barbour desc_write.descriptorCount = 1; 5662f18b292ff155af7df35930474857b507dbf18feTony Barbour desc_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; 5672f18b292ff155af7df35930474857b507dbf18feTony Barbour desc_write.pBufferInfo = &desc_bufs[i]; 5682f18b292ff155af7df35930474857b507dbf18feTony Barbour desc_writes[i] = desc_write; 5692f18b292ff155af7df35930474857b507dbf18feTony Barbour } 5702f18b292ff155af7df35930474857b507dbf18feTony Barbour 5712f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::UpdateDescriptorSets(dev_, 5722f18b292ff155af7df35930474857b507dbf18feTony Barbour static_cast<uint32_t>(desc_writes.size()), 5732f18b292ff155af7df35930474857b507dbf18feTony Barbour desc_writes.data(), 0, nullptr); 5742f18b292ff155af7df35930474857b507dbf18feTony Barbour} 5752f18b292ff155af7df35930474857b507dbf18feTony Barbour 5762f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::attach_swapchain() 5772f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 5782f18b292ff155af7df35930474857b507dbf18feTony Barbour const Shell::Context &ctx = shell_->context(); 5792f18b292ff155af7df35930474857b507dbf18feTony Barbour 5802f18b292ff155af7df35930474857b507dbf18feTony Barbour prepare_viewport(ctx.extent); 5812f18b292ff155af7df35930474857b507dbf18feTony Barbour prepare_framebuffers(ctx.swapchain); 5822f18b292ff155af7df35930474857b507dbf18feTony Barbour 5832f18b292ff155af7df35930474857b507dbf18feTony Barbour update_camera(); 5842f18b292ff155af7df35930474857b507dbf18feTony Barbour} 5852f18b292ff155af7df35930474857b507dbf18feTony Barbour 5862f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::detach_swapchain() 5872f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 5882f18b292ff155af7df35930474857b507dbf18feTony Barbour for (auto fb : framebuffers_) 5892f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::DestroyFramebuffer(dev_, fb, nullptr); 5902f18b292ff155af7df35930474857b507dbf18feTony Barbour for (auto view : image_views_) 5912f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::DestroyImageView(dev_, view, nullptr); 5922f18b292ff155af7df35930474857b507dbf18feTony Barbour 5932f18b292ff155af7df35930474857b507dbf18feTony Barbour framebuffers_.clear(); 5942f18b292ff155af7df35930474857b507dbf18feTony Barbour image_views_.clear(); 5952f18b292ff155af7df35930474857b507dbf18feTony Barbour images_.clear(); 5962f18b292ff155af7df35930474857b507dbf18feTony Barbour} 5972f18b292ff155af7df35930474857b507dbf18feTony Barbour 5982f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::prepare_viewport(const VkExtent2D &extent) 5992f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 6002f18b292ff155af7df35930474857b507dbf18feTony Barbour extent_ = extent; 6012f18b292ff155af7df35930474857b507dbf18feTony Barbour 6022f18b292ff155af7df35930474857b507dbf18feTony Barbour viewport_.x = 0.0f; 6032f18b292ff155af7df35930474857b507dbf18feTony Barbour viewport_.y = 0.0f; 6042f18b292ff155af7df35930474857b507dbf18feTony Barbour viewport_.width = static_cast<float>(extent.width); 6052f18b292ff155af7df35930474857b507dbf18feTony Barbour viewport_.height = static_cast<float>(extent.height); 6062f18b292ff155af7df35930474857b507dbf18feTony Barbour viewport_.minDepth = 0.0f; 6072f18b292ff155af7df35930474857b507dbf18feTony Barbour viewport_.maxDepth = 1.0f; 6082f18b292ff155af7df35930474857b507dbf18feTony Barbour 6092f18b292ff155af7df35930474857b507dbf18feTony Barbour scissor_.offset = { 0, 0 }; 6102f18b292ff155af7df35930474857b507dbf18feTony Barbour scissor_.extent = extent_; 6112f18b292ff155af7df35930474857b507dbf18feTony Barbour} 6122f18b292ff155af7df35930474857b507dbf18feTony Barbour 6132f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::prepare_framebuffers(VkSwapchainKHR swapchain) 6142f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 6152f18b292ff155af7df35930474857b507dbf18feTony Barbour // get swapchain images 6162f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::get(dev_, swapchain, images_); 6172f18b292ff155af7df35930474857b507dbf18feTony Barbour 6182f18b292ff155af7df35930474857b507dbf18feTony Barbour assert(framebuffers_.empty()); 6192f18b292ff155af7df35930474857b507dbf18feTony Barbour image_views_.reserve(images_.size()); 6202f18b292ff155af7df35930474857b507dbf18feTony Barbour framebuffers_.reserve(images_.size()); 6212f18b292ff155af7df35930474857b507dbf18feTony Barbour for (auto img : images_) { 6222f18b292ff155af7df35930474857b507dbf18feTony Barbour VkImageViewCreateInfo view_info = {}; 6232f18b292ff155af7df35930474857b507dbf18feTony Barbour view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 6242f18b292ff155af7df35930474857b507dbf18feTony Barbour view_info.image = img; 6252f18b292ff155af7df35930474857b507dbf18feTony Barbour view_info.viewType = VK_IMAGE_VIEW_TYPE_2D; 6262f18b292ff155af7df35930474857b507dbf18feTony Barbour view_info.format = format_; 6272f18b292ff155af7df35930474857b507dbf18feTony Barbour view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 6282f18b292ff155af7df35930474857b507dbf18feTony Barbour view_info.subresourceRange.levelCount = 1; 6292f18b292ff155af7df35930474857b507dbf18feTony Barbour view_info.subresourceRange.layerCount = 1; 6302f18b292ff155af7df35930474857b507dbf18feTony Barbour 6312f18b292ff155af7df35930474857b507dbf18feTony Barbour VkImageView view; 6322f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::assert_success(vk::CreateImageView(dev_, &view_info, nullptr, &view)); 6332f18b292ff155af7df35930474857b507dbf18feTony Barbour image_views_.push_back(view); 6342f18b292ff155af7df35930474857b507dbf18feTony Barbour 6352f18b292ff155af7df35930474857b507dbf18feTony Barbour VkFramebufferCreateInfo fb_info = {}; 6362f18b292ff155af7df35930474857b507dbf18feTony Barbour fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; 6372f18b292ff155af7df35930474857b507dbf18feTony Barbour fb_info.renderPass = render_pass_; 6382f18b292ff155af7df35930474857b507dbf18feTony Barbour fb_info.attachmentCount = 1; 6392f18b292ff155af7df35930474857b507dbf18feTony Barbour fb_info.pAttachments = &view; 6402f18b292ff155af7df35930474857b507dbf18feTony Barbour fb_info.width = extent_.width; 6412f18b292ff155af7df35930474857b507dbf18feTony Barbour fb_info.height = extent_.height; 6422f18b292ff155af7df35930474857b507dbf18feTony Barbour fb_info.layers = 1; 6432f18b292ff155af7df35930474857b507dbf18feTony Barbour 6442f18b292ff155af7df35930474857b507dbf18feTony Barbour VkFramebuffer fb; 6452f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::assert_success(vk::CreateFramebuffer(dev_, &fb_info, nullptr, &fb)); 6462f18b292ff155af7df35930474857b507dbf18feTony Barbour framebuffers_.push_back(fb); 6472f18b292ff155af7df35930474857b507dbf18feTony Barbour } 6482f18b292ff155af7df35930474857b507dbf18feTony Barbour} 6492f18b292ff155af7df35930474857b507dbf18feTony Barbour 6502f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::update_camera() 6512f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 6522f18b292ff155af7df35930474857b507dbf18feTony Barbour const glm::vec3 center(0.0f); 6532f18b292ff155af7df35930474857b507dbf18feTony Barbour const glm::vec3 up(0.f, 0.0f, 1.0f); 6542f18b292ff155af7df35930474857b507dbf18feTony Barbour const glm::mat4 view = glm::lookAt(camera_.eye_pos, center, up); 6552f18b292ff155af7df35930474857b507dbf18feTony Barbour 6562f18b292ff155af7df35930474857b507dbf18feTony Barbour float aspect = static_cast<float>(extent_.width) / static_cast<float>(extent_.height); 6572f18b292ff155af7df35930474857b507dbf18feTony Barbour const glm::mat4 projection = glm::perspective(0.4f, aspect, 0.1f, 100.0f); 6582f18b292ff155af7df35930474857b507dbf18feTony Barbour 6592f18b292ff155af7df35930474857b507dbf18feTony Barbour // Vulkan clip space has inverted Y and half Z. 6602f18b292ff155af7df35930474857b507dbf18feTony Barbour const glm::mat4 clip(1.0f, 0.0f, 0.0f, 0.0f, 6612f18b292ff155af7df35930474857b507dbf18feTony Barbour 0.0f, -1.0f, 0.0f, 0.0f, 6622f18b292ff155af7df35930474857b507dbf18feTony Barbour 0.0f, 0.0f, 0.5f, 0.0f, 6632f18b292ff155af7df35930474857b507dbf18feTony Barbour 0.0f, 0.0f, 0.5f, 1.0f); 6642f18b292ff155af7df35930474857b507dbf18feTony Barbour 6652f18b292ff155af7df35930474857b507dbf18feTony Barbour camera_.view_projection = clip * projection * view; 6662f18b292ff155af7df35930474857b507dbf18feTony Barbour} 6672f18b292ff155af7df35930474857b507dbf18feTony Barbour 6682f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::draw_object(const Simulation::Object &obj, FrameData &data, VkCommandBuffer cmd) const 6692f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 6702f18b292ff155af7df35930474857b507dbf18feTony Barbour if (use_push_constants_) { 6712f18b292ff155af7df35930474857b507dbf18feTony Barbour ShaderParamBlock params; 6722f18b292ff155af7df35930474857b507dbf18feTony Barbour memcpy(params.light_pos, glm::value_ptr(obj.light_pos), sizeof(obj.light_pos)); 6732f18b292ff155af7df35930474857b507dbf18feTony Barbour memcpy(params.light_color, glm::value_ptr(obj.light_color), sizeof(obj.light_color)); 6742f18b292ff155af7df35930474857b507dbf18feTony Barbour memcpy(params.model, glm::value_ptr(obj.model), sizeof(obj.model)); 6752f18b292ff155af7df35930474857b507dbf18feTony Barbour memcpy(params.view_projection, glm::value_ptr(camera_.view_projection), sizeof(camera_.view_projection)); 6762f18b292ff155af7df35930474857b507dbf18feTony Barbour 6772f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::CmdPushConstants(cmd, pipeline_layout_, VK_SHADER_STAGE_VERTEX_BIT, 6782f18b292ff155af7df35930474857b507dbf18feTony Barbour 0, sizeof(params), ¶ms); 6792f18b292ff155af7df35930474857b507dbf18feTony Barbour } else { 6802f18b292ff155af7df35930474857b507dbf18feTony Barbour ShaderParamBlock *params = 6812f18b292ff155af7df35930474857b507dbf18feTony Barbour reinterpret_cast<ShaderParamBlock *>(data.base + obj.frame_data_offset); 6822f18b292ff155af7df35930474857b507dbf18feTony Barbour memcpy(params->light_pos, glm::value_ptr(obj.light_pos), sizeof(obj.light_pos)); 6832f18b292ff155af7df35930474857b507dbf18feTony Barbour memcpy(params->light_color, glm::value_ptr(obj.light_color), sizeof(obj.light_color)); 6842f18b292ff155af7df35930474857b507dbf18feTony Barbour memcpy(params->model, glm::value_ptr(obj.model), sizeof(obj.model)); 6852f18b292ff155af7df35930474857b507dbf18feTony Barbour memcpy(params->view_projection, glm::value_ptr(camera_.view_projection), sizeof(camera_.view_projection)); 6862f18b292ff155af7df35930474857b507dbf18feTony Barbour 6872f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::CmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, 6882f18b292ff155af7df35930474857b507dbf18feTony Barbour pipeline_layout_, 0, 1, &data.desc_set, 1, &obj.frame_data_offset); 6892f18b292ff155af7df35930474857b507dbf18feTony Barbour } 6902f18b292ff155af7df35930474857b507dbf18feTony Barbour 6912f18b292ff155af7df35930474857b507dbf18feTony Barbour meshes_->cmd_draw(cmd, obj.mesh); 6922f18b292ff155af7df35930474857b507dbf18feTony Barbour} 6932f18b292ff155af7df35930474857b507dbf18feTony Barbour 6942f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::update_simulation(const Worker &worker) 6952f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 6962f18b292ff155af7df35930474857b507dbf18feTony Barbour sim_.update(worker.tick_interval_, worker.object_begin_, worker.object_end_); 6972f18b292ff155af7df35930474857b507dbf18feTony Barbour} 6982f18b292ff155af7df35930474857b507dbf18feTony Barbour 6992f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::draw_objects(Worker &worker) 7002f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 7012f18b292ff155af7df35930474857b507dbf18feTony Barbour auto &data = frame_data_[frame_data_index_]; 7022f18b292ff155af7df35930474857b507dbf18feTony Barbour auto cmd = data.worker_cmds[worker.index_]; 7032f18b292ff155af7df35930474857b507dbf18feTony Barbour 7042f18b292ff155af7df35930474857b507dbf18feTony Barbour VkCommandBufferInheritanceInfo inherit_info = {}; 7052f18b292ff155af7df35930474857b507dbf18feTony Barbour inherit_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; 7062f18b292ff155af7df35930474857b507dbf18feTony Barbour inherit_info.renderPass = render_pass_; 7072f18b292ff155af7df35930474857b507dbf18feTony Barbour inherit_info.framebuffer = worker.fb_; 7082f18b292ff155af7df35930474857b507dbf18feTony Barbour 7092f18b292ff155af7df35930474857b507dbf18feTony Barbour VkCommandBufferBeginInfo begin_info = {}; 7102f18b292ff155af7df35930474857b507dbf18feTony Barbour begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 7112f18b292ff155af7df35930474857b507dbf18feTony Barbour begin_info.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; 7122f18b292ff155af7df35930474857b507dbf18feTony Barbour begin_info.pInheritanceInfo = &inherit_info; 7132f18b292ff155af7df35930474857b507dbf18feTony Barbour 7142f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::BeginCommandBuffer(cmd, &begin_info); 7152f18b292ff155af7df35930474857b507dbf18feTony Barbour 7162f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::CmdSetViewport(cmd, 0, 1, &viewport_); 7172f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::CmdSetScissor(cmd, 0, 1, &scissor_); 7182f18b292ff155af7df35930474857b507dbf18feTony Barbour 7192f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::CmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_); 7202f18b292ff155af7df35930474857b507dbf18feTony Barbour 7212f18b292ff155af7df35930474857b507dbf18feTony Barbour meshes_->cmd_bind_buffers(cmd); 7222f18b292ff155af7df35930474857b507dbf18feTony Barbour 7232f18b292ff155af7df35930474857b507dbf18feTony Barbour for (int i = worker.object_begin_; i < worker.object_end_; i++) { 7242f18b292ff155af7df35930474857b507dbf18feTony Barbour auto &obj = sim_.objects()[i]; 7252f18b292ff155af7df35930474857b507dbf18feTony Barbour 7262f18b292ff155af7df35930474857b507dbf18feTony Barbour draw_object(obj, data, cmd); 7272f18b292ff155af7df35930474857b507dbf18feTony Barbour } 7282f18b292ff155af7df35930474857b507dbf18feTony Barbour 7292f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::EndCommandBuffer(cmd); 7302f18b292ff155af7df35930474857b507dbf18feTony Barbour} 7312f18b292ff155af7df35930474857b507dbf18feTony Barbour 7322f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::on_key(Key key) 7332f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 7342f18b292ff155af7df35930474857b507dbf18feTony Barbour switch (key) { 7352f18b292ff155af7df35930474857b507dbf18feTony Barbour case KEY_SHUTDOWN: 7362f18b292ff155af7df35930474857b507dbf18feTony Barbour case KEY_ESC: 7372f18b292ff155af7df35930474857b507dbf18feTony Barbour shell_->quit(); 7382f18b292ff155af7df35930474857b507dbf18feTony Barbour break; 7392f18b292ff155af7df35930474857b507dbf18feTony Barbour case KEY_UP: 7402f18b292ff155af7df35930474857b507dbf18feTony Barbour camera_.eye_pos -= glm::vec3(0.05f); 7412f18b292ff155af7df35930474857b507dbf18feTony Barbour update_camera(); 7422f18b292ff155af7df35930474857b507dbf18feTony Barbour break; 7432f18b292ff155af7df35930474857b507dbf18feTony Barbour case KEY_DOWN: 7442f18b292ff155af7df35930474857b507dbf18feTony Barbour camera_.eye_pos += glm::vec3(0.05f); 7452f18b292ff155af7df35930474857b507dbf18feTony Barbour update_camera(); 7462f18b292ff155af7df35930474857b507dbf18feTony Barbour break; 7472f18b292ff155af7df35930474857b507dbf18feTony Barbour case KEY_SPACE: 7482f18b292ff155af7df35930474857b507dbf18feTony Barbour sim_paused_ = !sim_paused_; 7492f18b292ff155af7df35930474857b507dbf18feTony Barbour break; 7502f18b292ff155af7df35930474857b507dbf18feTony Barbour default: 7512f18b292ff155af7df35930474857b507dbf18feTony Barbour break; 7522f18b292ff155af7df35930474857b507dbf18feTony Barbour } 7532f18b292ff155af7df35930474857b507dbf18feTony Barbour} 7542f18b292ff155af7df35930474857b507dbf18feTony Barbour 7552f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::on_tick() 7562f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 7572f18b292ff155af7df35930474857b507dbf18feTony Barbour if (sim_paused_) 7582f18b292ff155af7df35930474857b507dbf18feTony Barbour return; 7592f18b292ff155af7df35930474857b507dbf18feTony Barbour 7602f18b292ff155af7df35930474857b507dbf18feTony Barbour for (auto &worker : workers_) 7612f18b292ff155af7df35930474857b507dbf18feTony Barbour worker->update_simulation(); 7622f18b292ff155af7df35930474857b507dbf18feTony Barbour} 7632f18b292ff155af7df35930474857b507dbf18feTony Barbour 7642f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::on_frame(float frame_pred) 7652f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 7662f18b292ff155af7df35930474857b507dbf18feTony Barbour auto &data = frame_data_[frame_data_index_]; 7672f18b292ff155af7df35930474857b507dbf18feTony Barbour 7682f18b292ff155af7df35930474857b507dbf18feTony Barbour // wait for the last submission since we reuse frame data 7692f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::assert_success(vk::WaitForFences(dev_, 1, &data.fence, true, UINT64_MAX)); 7702f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::assert_success(vk::ResetFences(dev_, 1, &data.fence)); 7712f18b292ff155af7df35930474857b507dbf18feTony Barbour 7722f18b292ff155af7df35930474857b507dbf18feTony Barbour const Shell::BackBuffer &back = shell_->context().acquired_back_buffer; 7732f18b292ff155af7df35930474857b507dbf18feTony Barbour 7742f18b292ff155af7df35930474857b507dbf18feTony Barbour // ignore frame_pred 7752f18b292ff155af7df35930474857b507dbf18feTony Barbour for (auto &worker : workers_) 7762f18b292ff155af7df35930474857b507dbf18feTony Barbour worker->draw_objects(framebuffers_[back.image_index]); 7772f18b292ff155af7df35930474857b507dbf18feTony Barbour 7782f18b292ff155af7df35930474857b507dbf18feTony Barbour VkResult res = vk::BeginCommandBuffer(data.primary_cmd, &primary_cmd_begin_info_); 7792f18b292ff155af7df35930474857b507dbf18feTony Barbour 7805122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz if (!use_push_constants_) { 7815122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz VkBufferMemoryBarrier buf_barrier = {}; 7825122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz buf_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; 7835122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz buf_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; 7845122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz buf_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 7855122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz buf_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 7865122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz buf_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 7875122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz buf_barrier.buffer = data.buf; 7885122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz buf_barrier.offset = 0; 7895122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz buf_barrier.size = VK_WHOLE_SIZE; 7905122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz vk::CmdPipelineBarrier(data.primary_cmd, 7915122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz VK_PIPELINE_STAGE_HOST_BIT, 7925122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 7935122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz 0, 0, nullptr, 1, &buf_barrier, 0, nullptr); 7945122cb1ddc48c8a98d4f5d4dc94f21aa92a3929cKarl Schultz } 7952f18b292ff155af7df35930474857b507dbf18feTony Barbour 7962f18b292ff155af7df35930474857b507dbf18feTony Barbour render_pass_begin_info_.framebuffer = framebuffers_[back.image_index]; 7972f18b292ff155af7df35930474857b507dbf18feTony Barbour render_pass_begin_info_.renderArea.extent = extent_; 7982f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::CmdBeginRenderPass(data.primary_cmd, &render_pass_begin_info_, 7992f18b292ff155af7df35930474857b507dbf18feTony Barbour VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS); 8002f18b292ff155af7df35930474857b507dbf18feTony Barbour 8012f18b292ff155af7df35930474857b507dbf18feTony Barbour // record render pass commands 8022f18b292ff155af7df35930474857b507dbf18feTony Barbour for (auto &worker : workers_) 8032f18b292ff155af7df35930474857b507dbf18feTony Barbour worker->wait_idle(); 8042f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::CmdExecuteCommands(data.primary_cmd, 8052f18b292ff155af7df35930474857b507dbf18feTony Barbour static_cast<uint32_t>(data.worker_cmds.size()), 8062f18b292ff155af7df35930474857b507dbf18feTony Barbour data.worker_cmds.data()); 8072f18b292ff155af7df35930474857b507dbf18feTony Barbour 8082f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::CmdEndRenderPass(data.primary_cmd); 8092f18b292ff155af7df35930474857b507dbf18feTony Barbour vk::EndCommandBuffer(data.primary_cmd); 8102f18b292ff155af7df35930474857b507dbf18feTony Barbour 8112f18b292ff155af7df35930474857b507dbf18feTony Barbour // wait for the image to be owned and signal for render completion 8122f18b292ff155af7df35930474857b507dbf18feTony Barbour primary_cmd_submit_info_.pWaitSemaphores = &back.acquire_semaphore; 8132f18b292ff155af7df35930474857b507dbf18feTony Barbour primary_cmd_submit_info_.pCommandBuffers = &data.primary_cmd; 8142f18b292ff155af7df35930474857b507dbf18feTony Barbour primary_cmd_submit_info_.pSignalSemaphores = &back.render_semaphore; 8152f18b292ff155af7df35930474857b507dbf18feTony Barbour 8162f18b292ff155af7df35930474857b507dbf18feTony Barbour res = vk::QueueSubmit(queue_, 1, &primary_cmd_submit_info_, data.fence); 8172f18b292ff155af7df35930474857b507dbf18feTony Barbour 8182f18b292ff155af7df35930474857b507dbf18feTony Barbour frame_data_index_ = (frame_data_index_ + 1) % frame_data_.size(); 8192f18b292ff155af7df35930474857b507dbf18feTony Barbour 8202f18b292ff155af7df35930474857b507dbf18feTony Barbour (void) res; 8212f18b292ff155af7df35930474857b507dbf18feTony Barbour} 8222f18b292ff155af7df35930474857b507dbf18feTony Barbour 8232f18b292ff155af7df35930474857b507dbf18feTony BarbourSmoke::Worker::Worker(Smoke &smoke, int index, int object_begin, int object_end) 8242f18b292ff155af7df35930474857b507dbf18feTony Barbour : smoke_(smoke), index_(index), 8252f18b292ff155af7df35930474857b507dbf18feTony Barbour object_begin_(object_begin), object_end_(object_end), 8262f18b292ff155af7df35930474857b507dbf18feTony Barbour tick_interval_(1.0f / smoke.settings_.ticks_per_second), state_(INIT) 8272f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 8282f18b292ff155af7df35930474857b507dbf18feTony Barbour} 8292f18b292ff155af7df35930474857b507dbf18feTony Barbour 8302f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::Worker::start() 8312f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 8322f18b292ff155af7df35930474857b507dbf18feTony Barbour state_ = IDLE; 8332f18b292ff155af7df35930474857b507dbf18feTony Barbour thread_ = std::thread(Smoke::Worker::thread_loop, this); 8342f18b292ff155af7df35930474857b507dbf18feTony Barbour} 8352f18b292ff155af7df35930474857b507dbf18feTony Barbour 8362f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::Worker::stop() 8372f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 8382f18b292ff155af7df35930474857b507dbf18feTony Barbour { 8392f18b292ff155af7df35930474857b507dbf18feTony Barbour std::lock_guard<std::mutex> lock(mutex_); 8402f18b292ff155af7df35930474857b507dbf18feTony Barbour state_ = INIT; 8412f18b292ff155af7df35930474857b507dbf18feTony Barbour } 8422f18b292ff155af7df35930474857b507dbf18feTony Barbour state_cv_.notify_one(); 8432f18b292ff155af7df35930474857b507dbf18feTony Barbour 8442f18b292ff155af7df35930474857b507dbf18feTony Barbour thread_.join(); 8452f18b292ff155af7df35930474857b507dbf18feTony Barbour} 8462f18b292ff155af7df35930474857b507dbf18feTony Barbour 8472f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::Worker::update_simulation() 8482f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 8492f18b292ff155af7df35930474857b507dbf18feTony Barbour { 8502f18b292ff155af7df35930474857b507dbf18feTony Barbour std::lock_guard<std::mutex> lock(mutex_); 8512f18b292ff155af7df35930474857b507dbf18feTony Barbour bool started = (state_ != INIT); 8522f18b292ff155af7df35930474857b507dbf18feTony Barbour 8532f18b292ff155af7df35930474857b507dbf18feTony Barbour state_ = STEP; 8542f18b292ff155af7df35930474857b507dbf18feTony Barbour 8552f18b292ff155af7df35930474857b507dbf18feTony Barbour // step directly 8562f18b292ff155af7df35930474857b507dbf18feTony Barbour if (!started) { 8572f18b292ff155af7df35930474857b507dbf18feTony Barbour smoke_.update_simulation(*this); 8582f18b292ff155af7df35930474857b507dbf18feTony Barbour state_ = INIT; 8592f18b292ff155af7df35930474857b507dbf18feTony Barbour } 8602f18b292ff155af7df35930474857b507dbf18feTony Barbour } 8612f18b292ff155af7df35930474857b507dbf18feTony Barbour state_cv_.notify_one(); 8622f18b292ff155af7df35930474857b507dbf18feTony Barbour} 8632f18b292ff155af7df35930474857b507dbf18feTony Barbour 8642f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::Worker::draw_objects(VkFramebuffer fb) 8652f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 8662f18b292ff155af7df35930474857b507dbf18feTony Barbour // wait for step_objects first 8672f18b292ff155af7df35930474857b507dbf18feTony Barbour wait_idle(); 8682f18b292ff155af7df35930474857b507dbf18feTony Barbour 8692f18b292ff155af7df35930474857b507dbf18feTony Barbour { 8702f18b292ff155af7df35930474857b507dbf18feTony Barbour std::lock_guard<std::mutex> lock(mutex_); 8712f18b292ff155af7df35930474857b507dbf18feTony Barbour bool started = (state_ != INIT); 8722f18b292ff155af7df35930474857b507dbf18feTony Barbour 8732f18b292ff155af7df35930474857b507dbf18feTony Barbour fb_ = fb; 8742f18b292ff155af7df35930474857b507dbf18feTony Barbour state_ = DRAW; 8752f18b292ff155af7df35930474857b507dbf18feTony Barbour 8762f18b292ff155af7df35930474857b507dbf18feTony Barbour // render directly 8772f18b292ff155af7df35930474857b507dbf18feTony Barbour if (!started) { 8782f18b292ff155af7df35930474857b507dbf18feTony Barbour smoke_.draw_objects(*this); 8792f18b292ff155af7df35930474857b507dbf18feTony Barbour state_ = INIT; 8802f18b292ff155af7df35930474857b507dbf18feTony Barbour } 8812f18b292ff155af7df35930474857b507dbf18feTony Barbour } 8822f18b292ff155af7df35930474857b507dbf18feTony Barbour state_cv_.notify_one(); 8832f18b292ff155af7df35930474857b507dbf18feTony Barbour} 8842f18b292ff155af7df35930474857b507dbf18feTony Barbour 8852f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::Worker::wait_idle() 8862f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 8872f18b292ff155af7df35930474857b507dbf18feTony Barbour std::unique_lock<std::mutex> lock(mutex_); 8882f18b292ff155af7df35930474857b507dbf18feTony Barbour bool started = (state_ != INIT); 8892f18b292ff155af7df35930474857b507dbf18feTony Barbour 8902f18b292ff155af7df35930474857b507dbf18feTony Barbour if (started) 8912f18b292ff155af7df35930474857b507dbf18feTony Barbour state_cv_.wait(lock, [this] { return (state_ == IDLE); }); 8922f18b292ff155af7df35930474857b507dbf18feTony Barbour} 8932f18b292ff155af7df35930474857b507dbf18feTony Barbour 8942f18b292ff155af7df35930474857b507dbf18feTony Barbourvoid Smoke::Worker::update_loop() 8952f18b292ff155af7df35930474857b507dbf18feTony Barbour{ 8962f18b292ff155af7df35930474857b507dbf18feTony Barbour while (true) { 8972f18b292ff155af7df35930474857b507dbf18feTony Barbour std::unique_lock<std::mutex> lock(mutex_); 8982f18b292ff155af7df35930474857b507dbf18feTony Barbour 8992f18b292ff155af7df35930474857b507dbf18feTony Barbour state_cv_.wait(lock, [this] { return (state_ != IDLE); }); 9002f18b292ff155af7df35930474857b507dbf18feTony Barbour if (state_ == INIT) 9012f18b292ff155af7df35930474857b507dbf18feTony Barbour break; 9022f18b292ff155af7df35930474857b507dbf18feTony Barbour 9032f18b292ff155af7df35930474857b507dbf18feTony Barbour assert(state_ == STEP || state_ == DRAW); 9042f18b292ff155af7df35930474857b507dbf18feTony Barbour if (state_ == STEP) 9052f18b292ff155af7df35930474857b507dbf18feTony Barbour smoke_.update_simulation(*this); 9062f18b292ff155af7df35930474857b507dbf18feTony Barbour else 9072f18b292ff155af7df35930474857b507dbf18feTony Barbour smoke_.draw_objects(*this); 9082f18b292ff155af7df35930474857b507dbf18feTony Barbour 9092f18b292ff155af7df35930474857b507dbf18feTony Barbour state_ = IDLE; 9102f18b292ff155af7df35930474857b507dbf18feTony Barbour lock.unlock(); 9112f18b292ff155af7df35930474857b507dbf18feTony Barbour state_cv_.notify_one(); 9122f18b292ff155af7df35930474857b507dbf18feTony Barbour } 9132f18b292ff155af7df35930474857b507dbf18feTony Barbour} 914