From f026a8c15705ebc425033f40235173703f0127e5 Mon Sep 17 00:00:00 2001 From: Benson Joeris Date: Thu, 31 Mar 2022 14:59:31 -0400 Subject: [PATCH 1/2] Copy timeline_semaphore_simple to synchronization2_timeline_semaphore_simple --- .../CMakeLists.txt | 31 ++ .../README.md | 6 + .../cube.frag | 25 + .../cube.vert | 32 ++ .../main.cpp | 466 ++++++++++++++++++ 5 files changed, 560 insertions(+) create mode 100644 application_sandbox/synchronization2_timeline_semaphore_simple/CMakeLists.txt create mode 100644 application_sandbox/synchronization2_timeline_semaphore_simple/README.md create mode 100644 application_sandbox/synchronization2_timeline_semaphore_simple/cube.frag create mode 100644 application_sandbox/synchronization2_timeline_semaphore_simple/cube.vert create mode 100644 application_sandbox/synchronization2_timeline_semaphore_simple/main.cpp diff --git a/application_sandbox/synchronization2_timeline_semaphore_simple/CMakeLists.txt b/application_sandbox/synchronization2_timeline_semaphore_simple/CMakeLists.txt new file mode 100644 index 00000000..ff88b099 --- /dev/null +++ b/application_sandbox/synchronization2_timeline_semaphore_simple/CMakeLists.txt @@ -0,0 +1,31 @@ +# Copyright 2019 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. + +add_shader_library(timeline_semaphore_simple_shaders + SOURCES + cube.frag + cube.vert + SHADER_DEPS + shader_library +) + +add_vulkan_sample_application(timeline_semaphore_simple + SOURCES main.cpp + LIBS + vulkan_helpers + MODELS + standard_models + SHADERS + timeline_semaphore_simple_shaders +) diff --git a/application_sandbox/synchronization2_timeline_semaphore_simple/README.md b/application_sandbox/synchronization2_timeline_semaphore_simple/README.md new file mode 100644 index 00000000..5f62490b --- /dev/null +++ b/application_sandbox/synchronization2_timeline_semaphore_simple/README.md @@ -0,0 +1,6 @@ +# Timeline Semaphore Simple + +Draws a simple cube on the screen. Inserts a timeline semaphore between +the VkAcquireNextImage and main Submission, and uses the same timeline +semaphore between the main submission and a dummy submission to signal +VkQueuePresentKHR. \ No newline at end of file diff --git a/application_sandbox/synchronization2_timeline_semaphore_simple/cube.frag b/application_sandbox/synchronization2_timeline_semaphore_simple/cube.frag new file mode 100644 index 00000000..bde692aa --- /dev/null +++ b/application_sandbox/synchronization2_timeline_semaphore_simple/cube.frag @@ -0,0 +1,25 @@ +/* Copyright 2019 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. + */ + +#version 450 + +layout(location = 0) out vec4 out_color; +layout (location = 1) in vec2 texcoord; + + + +void main() { + out_color = vec4(texcoord, 0.0, 1.0); +} \ No newline at end of file diff --git a/application_sandbox/synchronization2_timeline_semaphore_simple/cube.vert b/application_sandbox/synchronization2_timeline_semaphore_simple/cube.vert new file mode 100644 index 00000000..a613b3f8 --- /dev/null +++ b/application_sandbox/synchronization2_timeline_semaphore_simple/cube.vert @@ -0,0 +1,32 @@ +/* Copyright 2019 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. + */ + +#version 450 +#include "models/model_setup.glsl" + +layout (location = 1) out vec2 texcoord; + +layout (binding = 0, set = 0) uniform camera_data { + layout(column_major) mat4x4 projection; +}; + +layout (binding = 1, set = 0) uniform model_data { + layout(column_major) mat4x4 transform; +}; + +void main() { + gl_Position = projection * transform * get_position(); + texcoord = get_texcoord(); +} \ No newline at end of file diff --git a/application_sandbox/synchronization2_timeline_semaphore_simple/main.cpp b/application_sandbox/synchronization2_timeline_semaphore_simple/main.cpp new file mode 100644 index 00000000..1c2694d6 --- /dev/null +++ b/application_sandbox/synchronization2_timeline_semaphore_simple/main.cpp @@ -0,0 +1,466 @@ +// Copyright 2019 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. + +#include "application_sandbox/sample_application_framework/sample_application.h" +#include "mathfu/matrix.h" +#include "support/entry/entry.h" +#include "vulkan_helpers/buffer_frame_data.h" +#include "vulkan_helpers/vulkan_application.h" +#include "vulkan_helpers/vulkan_model.h" + +using Mat44 = mathfu::Matrix; + +struct camera_data_ { + Mat44 projection_matrix; +}; + +struct model_data_ { + Mat44 transform; +}; + +namespace cube_model { +#include "cube.obj.h" +} +const auto& cube_data = cube_model::model; + +uint32_t cube_vertex_shader[] = +#include "cube.vert.spv" + ; + +uint32_t cube_fragment_shader[] = +#include "cube.frag.spv" + ; + +struct FrameData { + containers::unique_ptr rendered_fence; + containers::unique_ptr swapchain_sema; + containers::unique_ptr present_ready_sema; + containers::unique_ptr command_buffer_; + containers::unique_ptr framebuffer_; + containers::unique_ptr cube_descriptor_set_; + containers::unique_ptr render_img_view_; +}; + +int main_entry(const entry::EntryData* data) { + logging::Logger* log = data->logger(); + log->LogInfo("Application Startup"); + + VkPhysicalDeviceTimelineSemaphoreFeaturesKHR timeline_semaphore_features{ + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR, + nullptr, + VK_TRUE, + }; + + vulkan::VulkanApplication app( + data->allocator(), data->logger(), data, + {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}, + {VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME}, {}, 131072, 131072, 131072, + 131072, false, false, false, 0, false, false, + VK_COLORSPACE_SRGB_NONLINEAR_KHR, false, false, nullptr, true, false, + &timeline_semaphore_features); + + vulkan::VkDevice& device = app.device(); + + size_t num_swapchain_images = app.swapchain_images().size(); + + vulkan::VkCommandBuffer initialization_command_buffer = + app.GetCommandBuffer(); + initialization_command_buffer->vkBeginCommandBuffer( + initialization_command_buffer, &sample_application::kBeginCommandBuffer); + + vulkan::VulkanModel cube(data->allocator(), data->logger(), cube_data); + cube.InitializeData(&app, &initialization_command_buffer); + + initialization_command_buffer->vkEndCommandBuffer( + initialization_command_buffer); + + VkSubmitInfo init_submit_info = sample_application::kEmptySubmitInfo; + init_submit_info.commandBufferCount = 1; + init_submit_info.pCommandBuffers = + &(initialization_command_buffer.get_command_buffer()); + + vulkan::VkFence init_fence = vulkan::CreateFence(&device); + + app.render_queue()->vkQueueSubmit(app.render_queue(), 1, &init_submit_info, + init_fence.get_raw_object()); + app.device()->vkWaitForFences(device, 1, &init_fence.get_raw_object(), false, + 0xFFFFFFFFFFFFFFFF); + + VkDescriptorSetLayoutBinding cube_descriptor_set_layouts_[2] = { + { + 0, // binding + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // descriptorType + 1, // descriptorCount + VK_SHADER_STAGE_VERTEX_BIT, // stageFlags + nullptr // pImmutableSamplers + }, + { + 1, // binding + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // descriptorType + 1, // descriptorCount + VK_SHADER_STAGE_VERTEX_BIT, // stageFlags + nullptr // pImmutableSamplers + }}; + + containers::unique_ptr pipeline_layout = + containers::make_unique( + data->allocator(), + app.CreatePipelineLayout({{cube_descriptor_set_layouts_[0], + cube_descriptor_set_layouts_[1]}})); + + VkAttachmentReference color_attachment = { + 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + + VkFormat render_target_format = app.swapchain().format(); + + VkSampleCountFlagBits num_samples = VK_SAMPLE_COUNT_1_BIT; + VkViewport viewport = {0.0f, + 0.0f, + static_cast(app.swapchain().width()), + static_cast(app.swapchain().height()), + 0.0f, + 1.0f}; + + VkRect2D scissor = {{0, 0}, + {app.swapchain().width(), app.swapchain().height()}}; + + containers::unique_ptr render_pass = + containers::make_unique( + data->allocator(), + app.CreateRenderPass( + {{ + 0, // flags + render_target_format, // format + num_samples, // samples + VK_ATTACHMENT_LOAD_OP_CLEAR, // loadOp + VK_ATTACHMENT_STORE_OP_STORE, // storeOp + VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp + VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp + VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR // finalLayout + }}, // AttachmentDescriptions + {{ + 0, // flags + VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint + 0, // inputAttachmentCount + nullptr, // pInputAttachments + 1, // colorAttachmentCount + &color_attachment, // colorAttachment + nullptr, // pResolveAttachments + nullptr, // pDepthStencilAttachment + 0, // preserveAttachmentCount + nullptr // pPreserveAttachments + }}, // SubpassDescriptions + {} // SubpassDependencies + )); + + containers::unique_ptr cube_pipeline = + containers::make_unique( + data->allocator(), app.CreateGraphicsPipeline(pipeline_layout.get(), + render_pass.get(), 0)); + cube_pipeline->AddShader(VK_SHADER_STAGE_VERTEX_BIT, "main", + cube_vertex_shader); + cube_pipeline->AddShader(VK_SHADER_STAGE_FRAGMENT_BIT, "main", + cube_fragment_shader); + cube_pipeline->SetTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); + cube_pipeline->SetInputStreams(&cube); + cube_pipeline->SetViewport(viewport); + cube_pipeline->SetScissor(scissor); + cube_pipeline->SetSamples(num_samples); + cube_pipeline->AddAttachment(); + cube_pipeline->Commit(); + + containers::unique_ptr> camera_data = + containers::make_unique>( + data->allocator(), &app, num_swapchain_images, + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + + containers::unique_ptr> model_data = + containers::make_unique>( + data->allocator(), &app, num_swapchain_images, + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); + + camera_data->data().projection_matrix = + Mat44::FromScaleVector(mathfu::Vector{1.0f, -1.0f, 1.0f}) * + Mat44::Perspective(1.5708f, 1.0f, 0.1f, 100.0f); + + model_data->data().transform = + Mat44::FromTranslationVector(mathfu::Vector{0.0f, 0.0f, -2.0f}); + + containers::vector frame_data(data->allocator()); + frame_data.resize(num_swapchain_images); + + for (int i = 0; i < num_swapchain_images; i++) { + FrameData& frame_data_i = frame_data[i]; + + frame_data_i.rendered_fence = containers::make_unique( + data->allocator(), vulkan::CreateFence(&device, true)); + frame_data_i.swapchain_sema = containers::make_unique( + data->allocator(), vulkan::CreateSemaphore(&device)); + frame_data_i.present_ready_sema = + containers::make_unique( + data->allocator(), vulkan::CreateSemaphore(&device)); + + VkImageViewCreateInfo render_img_view_create_info{ + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // sType + nullptr, // pNext + 0, // flags + app.swapchain_images()[i], // image + VK_IMAGE_VIEW_TYPE_2D, // viewType + render_target_format, // format + {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, + VK_COMPONENT_SWIZZLE_A}, + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + ::VkImageView raw_view; + LOG_ASSERT(==, data->logger(), VK_SUCCESS, + device->vkCreateImageView(device, &render_img_view_create_info, + nullptr, &raw_view)); + frame_data_i.render_img_view_ = + containers::make_unique( + data->allocator(), vulkan::VkImageView(raw_view, nullptr, &device)); + + frame_data_i.command_buffer_ = + containers::make_unique( + data->allocator(), app.GetCommandBuffer()); + + frame_data_i.cube_descriptor_set_ = + containers::make_unique( + data->allocator(), + app.AllocateDescriptorSet({cube_descriptor_set_layouts_[0], + cube_descriptor_set_layouts_[1]})); + + VkDescriptorBufferInfo buffer_infos[2] = { + { + camera_data->get_buffer(), // buffer + camera_data->get_offset_for_frame(i), // offset + camera_data->size(), // range + }, + { + model_data->get_buffer(), // buffer + model_data->get_offset_for_frame(i), // offset + model_data->size(), // range + }}; + + VkWriteDescriptorSet write{ + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType + nullptr, // pNext + *frame_data_i.cube_descriptor_set_, // dstSet + 0, // dstbinding + 0, // dstArrayElement + 2, // descriptorCount + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // descriptorType + nullptr, // pImageInfo + buffer_infos, // pBufferInfo + nullptr, // pTexelBufferView + }; + + device->vkUpdateDescriptorSets(device, 1, &write, 0, nullptr); + + // Create a framebuffer with the render image as the color attachment + VkFramebufferCreateInfo framebuffer_create_info{ + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // sType + nullptr, // pNext + 0, // flags + *render_pass, // renderPass + 1, // attachmentCount + &frame_data_i.render_img_view_->get_raw_object(), // attachments + app.swapchain().width(), // width + app.swapchain().height(), // height + 1 // layers + }; + + ::VkFramebuffer raw_framebuffer; + device->vkCreateFramebuffer(device, &framebuffer_create_info, nullptr, + &raw_framebuffer); + frame_data_i.framebuffer_ = containers::make_unique( + data->allocator(), + vulkan::VkFramebuffer(raw_framebuffer, nullptr, &device)); + + vulkan::VkCommandBuffer& cmdBuffer = (*frame_data_i.command_buffer_); + cmdBuffer->vkBeginCommandBuffer(cmdBuffer, + &sample_application::kBeginCommandBuffer); + + VkClearValue clear; + // Make the clear color white. + clear.color = {0.0, 0.0, 0.0, 1.0}; + + VkRenderPassBeginInfo pass_begin = { + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // sType + nullptr, // pNext + *render_pass, // renderPass + *frame_data_i.framebuffer_, // framebuffer + {{0, 0}, + {app.swapchain().width(), app.swapchain().height()}}, // renderArea + 1, // clearValueCount + &clear // clears + }; + + cmdBuffer->vkCmdBeginRenderPass(cmdBuffer, &pass_begin, + VK_SUBPASS_CONTENTS_INLINE); + + cmdBuffer->vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + *cube_pipeline); + cmdBuffer->vkCmdBindDescriptorSets( + cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + ::VkPipelineLayout(*pipeline_layout), 0, 1, + &frame_data_i.cube_descriptor_set_->raw_set(), 0, nullptr); + cube.Draw(&cmdBuffer); + cmdBuffer->vkCmdEndRenderPass(cmdBuffer); + + (*frame_data_i.command_buffer_) + ->vkEndCommandBuffer(*frame_data_i.command_buffer_); + } + + uint64_t zero = 0; + uint64_t signal_from_swap = 0; + uint64_t signal_to_swap = 0; + VkPipelineStageFlags waitStageMask = + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + VkTimelineSemaphoreSubmitInfoKHR timelineSubmitInfos[] = { + VkTimelineSemaphoreSubmitInfoKHR{ + VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR, // sType + nullptr, // pNext + 1, // waitSemaphoreValueCount + &zero, // waitSemaphoreValues, + 1, // signalSemaphoreValueCount + &signal_from_swap // signalSemaphoreValues + }, + VkTimelineSemaphoreSubmitInfoKHR{ + VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR, // sType + nullptr, // pNext + 1, // waitSemaphoreValueCount + &signal_from_swap, // waitSemaphoreValues, + 1, // signalSemaphoreValueCount + &signal_to_swap // signalSemaphoreValues + }, + VkTimelineSemaphoreSubmitInfoKHR{ + VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR, // sType + nullptr, // pNext + 1, // waitSemaphoreValueCount + &signal_to_swap, // waitSemaphoreValues, + 1, // signalSemaphoreValueCount + &zero // signalSemaphoreValues + }, + }; + + VkSubmitInfo submit_infos[] = {VkSubmitInfo{ + VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType + &timelineSubmitInfos[0], // pNext + 1, // waitSemaphoreCount + nullptr, // pWaitSemaphores + &waitStageMask, // pWaitDstStageMask, + 0, // commandBufferCount + nullptr, // pCommandBuffers + 1, // signalSemaphoreCount + nullptr // pSignalSemaphores + }, + VkSubmitInfo{ + VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType + &timelineSubmitInfos[1], // pNext + 1, // waitSemaphoreCount + nullptr, // pWaitSemaphores + &waitStageMask, // pWaitDstStageMask, + 1, // commandBufferCount + nullptr, // + 1, // signalSemaphoreCount + nullptr // pSignalSemaphores + }, + VkSubmitInfo{ + VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType + &timelineSubmitInfos[2], // pNext + 1, // waitSemaphoreCount + nullptr, // pWaitSemaphores + &waitStageMask, // pWaitDstStageMask, + 0, // commandBufferCount + nullptr, // pCommandBuffers + 1, // signalSemaphoreCount + nullptr // pSignalSemaphores + }}; + + // TimelineSemaphore + auto timelineSemaphore = vulkan::CreateTimelineSemaphore(&device, 0); + + uint32_t i = 0; + auto last_frame_time = std::chrono::high_resolution_clock::now(); + while (true) { + auto current_time = std::chrono::high_resolution_clock::now(); + std::chrono::duration elapsed_time = current_time - last_frame_time; + last_frame_time = current_time; + float fdt = data->fixed_timestep() ? 0.1f : elapsed_time.count(); + float speed = fdt; + uint32_t image_i; + + device->vkAcquireNextImageKHR( + device, app.swapchain().get_raw_object(), UINT64_MAX, + frame_data[i].swapchain_sema->get_raw_object(), + static_cast<::VkFence>(VK_NULL_HANDLE), &image_i); + + FrameData& frame_data_i = frame_data[image_i]; + + device->vkWaitForFences(device, 1, + &frame_data_i.rendered_fence->get_raw_object(), + VK_TRUE, UINT64_MAX); + device->vkResetFences(device, 1, + &frame_data_i.rendered_fence->get_raw_object()); + + camera_data->UpdateBuffer(&app.render_queue(), image_i); + model_data->UpdateBuffer(&app.render_queue(), image_i); + + model_data->data().transform = + model_data->data().transform * + Mat44::FromRotationMatrix(Mat44::RotationX(3.14f * speed) * + Mat44::RotationY(3.14f * speed * 0.5f)); + + signal_from_swap = signal_to_swap + 1; + signal_to_swap = signal_from_swap + 1; + + submit_infos[0].pWaitSemaphores = + &frame_data[i].swapchain_sema->get_raw_object(); + submit_infos[0].pSignalSemaphores = &timelineSemaphore.get_raw_object(); + + submit_infos[1].pCommandBuffers = + &frame_data_i.command_buffer_->get_command_buffer(); + submit_infos[1].pWaitSemaphores = &timelineSemaphore.get_raw_object(); + submit_infos[1].pSignalSemaphores = &timelineSemaphore.get_raw_object(); + + submit_infos[2].pWaitSemaphores = &timelineSemaphore.get_raw_object(); + submit_infos[2].pSignalSemaphores = + &frame_data[i].present_ready_sema->get_raw_object(); + + LOG_ASSERT(==, log, VK_SUCCESS, + app.render_queue()->vkQueueSubmit( + app.render_queue(), 3, &submit_infos[0], + frame_data_i.rendered_fence->get_raw_object())); + + VkPresentInfoKHR present_info{ + VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, // sType + nullptr, // pNext + 1, // waitSemaphoreCount + &frame_data[i++] + .present_ready_sema->get_raw_object(), // pWaitSemaphores + 1, // swapchainCount + &app.swapchain().get_raw_object(), // pSwapchains + &image_i, // pImageIndices + nullptr, // pResults + }; + i %= num_swapchain_images; + LOG_ASSERT(==, log, + app.present_queue()->vkQueuePresentKHR(app.present_queue(), + &present_info), + VK_SUCCESS); + } + + log->LogInfo("Application Shutdown"); + return 0; +} From 1649156438c722bb54e8a80b54df481b7f011a1d Mon Sep 17 00:00:00 2001 From: Benson Joeris Date: Thu, 31 Mar 2022 16:01:55 -0400 Subject: [PATCH 2/2] Add synchronization2_timeline_semaphore_simple --- application_sandbox/CMakeLists.txt | 3 +- .../CMakeLists.txt | 8 +- .../README.md | 8 +- .../main.cpp | 139 ++++++++---------- 4 files changed, 67 insertions(+), 91 deletions(-) diff --git a/application_sandbox/CMakeLists.txt b/application_sandbox/CMakeLists.txt index 65e31c2a..54b37b1a 100644 --- a/application_sandbox/CMakeLists.txt +++ b/application_sandbox/CMakeLists.txt @@ -128,8 +128,9 @@ add_vulkan_subdirectory(subgroup_ballot) add_vulkan_subdirectory(swapchain_colorspace) add_vulkan_subdirectory(subgroup_vote) add_vulkan_subdirectory(synchronization2_async_compute) -add_vulkan_subdirectory(synchronization2_set_event) add_vulkan_subdirectory(synchronization2_blit_image) +add_vulkan_subdirectory(synchronization2_set_event) +add_vulkan_subdirectory(synchronization2_timeline_semaphore_simple) add_vulkan_subdirectory(synchronization2_write_timestamp) add_vulkan_subdirectory(texel_buffer_alignment) add_vulkan_subdirectory(textured_cube) diff --git a/application_sandbox/synchronization2_timeline_semaphore_simple/CMakeLists.txt b/application_sandbox/synchronization2_timeline_semaphore_simple/CMakeLists.txt index ff88b099..2752769a 100644 --- a/application_sandbox/synchronization2_timeline_semaphore_simple/CMakeLists.txt +++ b/application_sandbox/synchronization2_timeline_semaphore_simple/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2019 Google Inc. +# Copyright 2022 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -add_shader_library(timeline_semaphore_simple_shaders +add_shader_library(synchronization2_timeline_semaphore_simple_shaders SOURCES cube.frag cube.vert @@ -20,12 +20,12 @@ add_shader_library(timeline_semaphore_simple_shaders shader_library ) -add_vulkan_sample_application(timeline_semaphore_simple +add_vulkan_sample_application(synchronization2_timeline_semaphore_simple SOURCES main.cpp LIBS vulkan_helpers MODELS standard_models SHADERS - timeline_semaphore_simple_shaders + synchronization2_timeline_semaphore_simple_shaders ) diff --git a/application_sandbox/synchronization2_timeline_semaphore_simple/README.md b/application_sandbox/synchronization2_timeline_semaphore_simple/README.md index 5f62490b..30693ae2 100644 --- a/application_sandbox/synchronization2_timeline_semaphore_simple/README.md +++ b/application_sandbox/synchronization2_timeline_semaphore_simple/README.md @@ -1,6 +1,4 @@ -# Timeline Semaphore Simple +# Timeline Semaphore Simple (VK_KHR_synchronization2 version) -Draws a simple cube on the screen. Inserts a timeline semaphore between -the VkAcquireNextImage and main Submission, and uses the same timeline -semaphore between the main submission and a dummy submission to signal -VkQueuePresentKHR. \ No newline at end of file +This is based on the timeline_semaphore_simple sample, using the VK_KHR_synchronization2 +extension. Specifically, this uses the vkQueueSubmit2KHR and VkSemaphoreSubmitInfoKHR. \ No newline at end of file diff --git a/application_sandbox/synchronization2_timeline_semaphore_simple/main.cpp b/application_sandbox/synchronization2_timeline_semaphore_simple/main.cpp index 1c2694d6..7c52f361 100644 --- a/application_sandbox/synchronization2_timeline_semaphore_simple/main.cpp +++ b/application_sandbox/synchronization2_timeline_semaphore_simple/main.cpp @@ -1,4 +1,4 @@ -// Copyright 2019 Google Inc. +// Copyright 2022 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -62,13 +62,20 @@ int main_entry(const entry::EntryData* data) { VK_TRUE, }; + static const VkDeviceSize kBufferSize = 131072u; // 128 KB + vulkan::VulkanApplication app( data->allocator(), data->logger(), data, - {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME}, - {VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME}, {}, 131072, 131072, 131072, - 131072, false, false, false, 0, false, false, - VK_COLORSPACE_SRGB_NONLINEAR_KHR, false, false, nullptr, true, false, - &timeline_semaphore_features); + vulkan::VulkanApplicationOptions() + .SetHostBufferSize(kBufferSize) + .SetDeviceImageSize(kBufferSize) + .SetDeviceBufferSize(kBufferSize) + .SetCoherentBufferSize(kBufferSize) + .SetDeviceExtensions(&timeline_semaphore_features) + .SetVulkanApiVersion(VK_API_VERSION_1_1), + {}, + {VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME, + VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME}); vulkan::VkDevice& device = app.device(); @@ -322,71 +329,31 @@ int main_entry(const entry::EntryData* data) { ->vkEndCommandBuffer(*frame_data_i.command_buffer_); } - uint64_t zero = 0; uint64_t signal_from_swap = 0; uint64_t signal_to_swap = 0; - VkPipelineStageFlags waitStageMask = - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - VkTimelineSemaphoreSubmitInfoKHR timelineSubmitInfos[] = { - VkTimelineSemaphoreSubmitInfoKHR{ - VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR, // sType - nullptr, // pNext - 1, // waitSemaphoreValueCount - &zero, // waitSemaphoreValues, - 1, // signalSemaphoreValueCount - &signal_from_swap // signalSemaphoreValues - }, - VkTimelineSemaphoreSubmitInfoKHR{ - VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR, // sType - nullptr, // pNext - 1, // waitSemaphoreValueCount - &signal_from_swap, // waitSemaphoreValues, - 1, // signalSemaphoreValueCount - &signal_to_swap // signalSemaphoreValues - }, - VkTimelineSemaphoreSubmitInfoKHR{ - VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR, // sType - nullptr, // pNext - 1, // waitSemaphoreValueCount - &signal_to_swap, // waitSemaphoreValues, - 1, // signalSemaphoreValueCount - &zero // signalSemaphoreValues - }, - }; - VkSubmitInfo submit_infos[] = {VkSubmitInfo{ - VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType - &timelineSubmitInfos[0], // pNext - 1, // waitSemaphoreCount - nullptr, // pWaitSemaphores - &waitStageMask, // pWaitDstStageMask, - 0, // commandBufferCount - nullptr, // pCommandBuffers - 1, // signalSemaphoreCount - nullptr // pSignalSemaphores - }, - VkSubmitInfo{ - VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType - &timelineSubmitInfos[1], // pNext - 1, // waitSemaphoreCount - nullptr, // pWaitSemaphores - &waitStageMask, // pWaitDstStageMask, - 1, // commandBufferCount - nullptr, // - 1, // signalSemaphoreCount - nullptr // pSignalSemaphores - }, - VkSubmitInfo{ - VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType - &timelineSubmitInfos[2], // pNext - 1, // waitSemaphoreCount - nullptr, // pWaitSemaphores - &waitStageMask, // pWaitDstStageMask, - 0, // commandBufferCount - nullptr, // pCommandBuffers - 1, // signalSemaphoreCount - nullptr // pSignalSemaphores - }}; + VkSemaphoreSubmitInfoKHR wait_semaphore_submit_infos[3] = {}; + VkSemaphoreSubmitInfoKHR signal_semaphore_submit_infos[3] = {}; + VkSubmitInfo2KHR submit_infos[3] = {}; + VkCommandBufferSubmitInfoKHR cb_submit_info = { + VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR}; + + for (uint32_t i = 0; i < 3; ++i) { + auto& wait_sem = wait_semaphore_submit_infos[i]; + auto& signal_sem = signal_semaphore_submit_infos[i]; + auto& submit_info = submit_infos[i]; + wait_sem.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR; + wait_sem.stageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR; + signal_sem.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR; + signal_sem.stageMask = + VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR; // TODO: can this be + // narrowed? + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR; + submit_info.waitSemaphoreInfoCount = 1; + submit_info.pWaitSemaphoreInfos = &wait_sem; + submit_info.signalSemaphoreInfoCount = 1; + submit_info.pSignalSemaphoreInfos = &signal_sem; + } // TimelineSemaphore auto timelineSemaphore = vulkan::CreateTimelineSemaphore(&device, 0); @@ -425,21 +392,31 @@ int main_entry(const entry::EntryData* data) { signal_from_swap = signal_to_swap + 1; signal_to_swap = signal_from_swap + 1; - submit_infos[0].pWaitSemaphores = - &frame_data[i].swapchain_sema->get_raw_object(); - submit_infos[0].pSignalSemaphores = &timelineSemaphore.get_raw_object(); - - submit_infos[1].pCommandBuffers = - &frame_data_i.command_buffer_->get_command_buffer(); - submit_infos[1].pWaitSemaphores = &timelineSemaphore.get_raw_object(); - submit_infos[1].pSignalSemaphores = &timelineSemaphore.get_raw_object(); - - submit_infos[2].pWaitSemaphores = &timelineSemaphore.get_raw_object(); - submit_infos[2].pSignalSemaphores = - &frame_data[i].present_ready_sema->get_raw_object(); + wait_semaphore_submit_infos[0].semaphore = + frame_data[i].swapchain_sema->get_raw_object(); + signal_semaphore_submit_infos[0].semaphore = + timelineSemaphore.get_raw_object(); + signal_semaphore_submit_infos[0].value = signal_from_swap; + + cb_submit_info.commandBuffer = + frame_data_i.command_buffer_->get_command_buffer(); + submit_infos[1].commandBufferInfoCount = 1; + submit_infos[1].pCommandBufferInfos = &cb_submit_info; + wait_semaphore_submit_infos[1].semaphore = + timelineSemaphore.get_raw_object(); + wait_semaphore_submit_infos[1].value = signal_from_swap; + signal_semaphore_submit_infos[1].semaphore = + timelineSemaphore.get_raw_object(); + signal_semaphore_submit_infos[1].value = signal_to_swap; + + wait_semaphore_submit_infos[2].semaphore = + timelineSemaphore.get_raw_object(); + wait_semaphore_submit_infos[2].value = signal_to_swap; + signal_semaphore_submit_infos[2].semaphore = + frame_data[i].present_ready_sema->get_raw_object(); LOG_ASSERT(==, log, VK_SUCCESS, - app.render_queue()->vkQueueSubmit( + app.render_queue()->vkQueueSubmit2KHR( app.render_queue(), 3, &submit_infos[0], frame_data_i.rendered_fence->get_raw_object()));