diff --git a/.github/workflows/cross-platform-check.yml b/.github/workflows/cross-platform-check.yml index e695c3b9..c2284491 100644 --- a/.github/workflows/cross-platform-check.yml +++ b/.github/workflows/cross-platform-check.yml @@ -116,7 +116,7 @@ jobs: cxx: "cl" } # note: if a specific vulkan version needs testing, you can add it here: - vulkan-sdk: ["latest", "1.3.204.1"] + vulkan-sdk: ["latest", "1.3.216.0"] steps: # IMPORTANT: apparently checkout@v3 pulls to ${{ github.event.repository.name }}/${{ github.event.repository.name }} instead of just ${{ github.event.repository.name }} on windows @@ -177,7 +177,7 @@ jobs: cxx: "cl" } # note: if a specific vulkan version needs testing, you can add it here: - vulkan-sdk: ["latest", "1.3.204.1"] + vulkan-sdk: ["latest", "1.3.216.0"] steps: # IMPORTANT: apparently checkout@v3 pulls to ${{ github.event.repository.name }}/${{ github.event.repository.name }} instead of just ${{ github.event.repository.name }} on windows diff --git a/CMakeLists.txt b/CMakeLists.txt index dad60f40..a099d7a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ option(avk_toolkit_CreateDependencySymlinks "Create symbolic links instead of co option(avk_toolkit_BuildExamples "Build all examples for Auto-Vk-Toolkit." OFF) option(avk_toolkit_BuildHelloWorld "Build example: hello_world." OFF) option(avk_toolkit_BuildFramebuffer "Build example: framebuffer." OFF) +option(avk_toolkit_BuildDynamicRendering "Build example: dynamic_rendering." OFF) option(avk_toolkit_BuildComputeImageProcessing "Build example: compute_image_processing." OFF) option(avk_toolkit_BuildMultiInvokeeRendering "Build example: multi_invokee_rendering." OFF) option(avk_toolkit_BuildModelLoader "Build example: model_loader." OFF) @@ -57,6 +58,7 @@ option(avk_toolkit_BuildPresentFromCompute "Build example: present_from_compute. if (avk_toolkit_BuildExamples) set(avk_toolkit_BuildHelloWorld ON) set(avk_toolkit_BuildFramebuffer ON) + set(avk_toolkit_BuildDynamicRendering ON) set(avk_toolkit_BuildComputeImageProcessing ON) set(avk_toolkit_BuildMultiInvokeeRendering ON) set(avk_toolkit_BuildModelLoader ON) @@ -226,6 +228,11 @@ if (avk_toolkit_BuildFramebuffer) add_subdirectory(examples/framebuffer) endif() +## dynamic_rendering +if (avk_toolkit_BuildDynamicRendering) + add_subdirectory(examples/dynamic_rendering) +endif() + ## compute_image_processing if (avk_toolkit_BuildComputeImageProcessing) add_subdirectory(examples/compute_image_processing) diff --git a/auto_vk b/auto_vk index a260d0bf..2e437e0c 160000 --- a/auto_vk +++ b/auto_vk @@ -1 +1 @@ -Subproject commit a260d0bf282402603bbff50de56d452af6a4ebb1 +Subproject commit 2e437e0c36f0a5322635a6567cb12768aa4769a0 diff --git a/auto_vk_toolkit/include/context_vulkan.hpp b/auto_vk_toolkit/include/context_vulkan.hpp index 6e78ab61..b29627da 100644 --- a/auto_vk_toolkit/include/context_vulkan.hpp +++ b/auto_vk_toolkit/include/context_vulkan.hpp @@ -226,6 +226,8 @@ namespace avk #endif bool supports_mesh_shader_nv(const vk::PhysicalDevice& device); bool is_mesh_shader_nv_requested(); + bool supports_dynamic_rendering(const vk::PhysicalDevice& device); + bool is_dynamic_rendering_requested(); #if VK_HEADER_VERSION >= 162 bool ray_tracing_pipeline_extension_requested(); diff --git a/auto_vk_toolkit/src/context_vulkan.cpp b/auto_vk_toolkit/src/context_vulkan.cpp index 2768eac6..2b935d99 100644 --- a/auto_vk_toolkit/src/context_vulkan.cpp +++ b/auto_vk_toolkit/src/context_vulkan.cpp @@ -293,6 +293,14 @@ namespace avk deviceFeatures.setPNext(&meshShaderFeatureNV); } + auto dynamicRenderingFeature = VkPhysicalDeviceDynamicRenderingFeaturesKHR{}; + dynamicRenderingFeature.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR; + dynamicRenderingFeature.dynamicRendering = VK_TRUE; + if(is_dynamic_rendering_requested() && supports_dynamic_rendering(context().physical_device())){ + dynamicRenderingFeature.pNext = deviceFeatures.pNext; + deviceFeatures.setPNext(&dynamicRenderingFeature); + } + // Unconditionally enable Synchronization2, because synchronization abstraction depends on it; it is just not implemented for Synchronization1: auto physicalDeviceSync2Features = vk::PhysicalDeviceSynchronization2FeaturesKHR{} .setPNext(deviceFeatures.pNext) @@ -912,6 +920,18 @@ namespace avk } #endif + bool context_vulkan::supports_dynamic_rendering(const vk::PhysicalDevice& device) + { + vk::PhysicalDeviceProperties2 physicalProperties; + device.getProperties2(&physicalProperties, dispatch_loader_core()); + + vk::PhysicalDeviceFeatures2 supportedExtFeatures; + auto dynamicRenderingFeatures = vk::PhysicalDeviceDynamicRenderingFeaturesKHR{}; + supportedExtFeatures.pNext = &dynamicRenderingFeatures; + device.getFeatures2(&supportedExtFeatures, dispatch_loader_core()); + return dynamicRenderingFeatures.dynamicRendering == VK_TRUE; + } + bool context_vulkan::supports_mesh_shader_nv(const vk::PhysicalDevice& device) { vk::PhysicalDeviceFeatures2 supportedExtFeatures; @@ -926,6 +946,11 @@ namespace avk const auto& devex = get_all_enabled_device_extensions(); return std::find(std::begin(devex), std::end(devex), std::string(VK_NV_MESH_SHADER_EXTENSION_NAME)) != std::end(devex); } + bool context_vulkan::is_dynamic_rendering_requested() + { + const auto& devex = get_all_enabled_device_extensions(); + return std::find(std::begin(devex), std::end(devex), std::string(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME)) != std::end(devex); + } #if VK_HEADER_VERSION >= 162 bool context_vulkan::ray_tracing_pipeline_extension_requested() diff --git a/examples/compute_image_processing/source/compute_image_processing.cpp b/examples/compute_image_processing/source/compute_image_processing.cpp index cbaeb5f7..b9c7ecd7 100644 --- a/examples/compute_image_processing/source/compute_image_processing.cpp +++ b/examples/compute_image_processing/source/compute_image_processing.cpp @@ -285,7 +285,7 @@ class compute_image_processing_app : public avk::invokee auto submission = avk::context().record({ // Begin and end one renderpass: - avk::command::render_pass(mGraphicsPipeline->renderpass_reference(), avk::context().main_window()->current_backbuffer_reference(), { + avk::command::render_pass(mGraphicsPipeline->renderpass_reference().value(), avk::context().main_window()->current_backbuffer_reference(), { // Draw left viewport: avk::command::custom_commands([&,this](avk::command_buffer_t& cb) { // If there is no avk::command::... struct for a particular command, we can always use avk::command::custom_commands diff --git a/examples/dynamic_rendering/CMakeLists.txt b/examples/dynamic_rendering/CMakeLists.txt new file mode 100644 index 00000000..1a2972e3 --- /dev/null +++ b/examples/dynamic_rendering/CMakeLists.txt @@ -0,0 +1,13 @@ +add_executable(dynamic_rendering + source/dynamic_rendering.cpp) +target_include_directories(dynamic_rendering PRIVATE ${PROJECT_NAME}) +target_link_libraries(dynamic_rendering PRIVATE ${PROJECT_NAME}) + +get_target_property(dynamic_rendering_BINARY_DIR dynamic_rendering BINARY_DIR) + +add_post_build_commands(dynamic_rendering + ${PROJECT_SOURCE_DIR}/examples/dynamic_rendering/shaders + ${dynamic_rendering_BINARY_DIR}/shaders + $/assets + "" + ${avk_toolkit_CreateDependencySymlinks}) \ No newline at end of file diff --git a/examples/dynamic_rendering/dynamic_rendering.md b/examples/dynamic_rendering/dynamic_rendering.md new file mode 100644 index 00000000..0d0e7f3e --- /dev/null +++ b/examples/dynamic_rendering/dynamic_rendering.md @@ -0,0 +1,4 @@ +# "Dynamic rendering" Example's Root Folder + +This is the root directory of the "Dynamic rendering" example. It contains all the source code for the example. + diff --git a/examples/dynamic_rendering/shaders/color.frag b/examples/dynamic_rendering/shaders/color.frag new file mode 100644 index 00000000..84daf5e0 --- /dev/null +++ b/examples/dynamic_rendering/shaders/color.frag @@ -0,0 +1,10 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(location = 0) in vec3 fragColor; + +layout(location = 0) out vec4 outColor; + +void main() { + outColor = vec4(fragColor, 1.0); +} diff --git a/examples/dynamic_rendering/shaders/screen_space_tri.vert b/examples/dynamic_rendering/shaders/screen_space_tri.vert new file mode 100644 index 00000000..1a17ce48 --- /dev/null +++ b/examples/dynamic_rendering/shaders/screen_space_tri.vert @@ -0,0 +1,21 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +layout(location = 0) out vec3 fragColor; + +const vec2[] positions = vec2[3] ( + vec2( 0.5, 0.5), + vec2( 0.0, -0.5), + vec2(-0.5, 0.5) +); + +const vec3[] colors = vec3[3] ( + vec3( 1.0, 0.0, 0.0), + vec3( 0.0, 1.0, 0.0), + vec3( 0.0, 0.0, 1.0) +); + +void main() { + gl_Position = vec4(positions[gl_VertexIndex], 0.5, 1.0); + fragColor = colors[gl_VertexIndex]; +} diff --git a/examples/dynamic_rendering/source/dynamic_rendering.cpp b/examples/dynamic_rendering/source/dynamic_rendering.cpp new file mode 100644 index 00000000..de722ecd --- /dev/null +++ b/examples/dynamic_rendering/source/dynamic_rendering.cpp @@ -0,0 +1,298 @@ +#include "avk/attachment.hpp" +#include "avk/command_buffer.hpp" +#include "avk/commands.hpp" +#include "avk/layout.hpp" +#include "avk/memory_access.hpp" +#include "avk/pipeline_stage.hpp" +#include "imgui.h" + +#include "configure_and_compose.hpp" +#include "imgui_manager.hpp" +#include "invokee.hpp" +#include "sequential_invoker.hpp" + +#include "context_vulkan.hpp" +#include +#include +#include +#include + +class dynamic_rendering_app : public avk::invokee +{ +public: // v== avk::invokee overrides which will be invoked by the framework ==v + dynamic_rendering_app(avk::queue& aQueue) + : mQueue{ &aQueue } + , mXSplit{960u} + , mYSplit{540u} + , mBorderThickness{2u} + , mFullscreenViewport{true} + , mClearColors{{ + {0.25f, 0.25f, 0.25f, 0.25f}, + {0.50f, 0.50f, 0.50f, 0.50f}, + {0.75f, 0.75f, 0.75f, 0.75f}, + {1.00f, 1.00f, 1.00f, 1.00f}, + }} + { } + + void initialize() override + { + const auto r = avk::context().main_window()->resolution(); + mColorImage = avk::context().create_image( + r.x, r.y, + {avk::context().main_window()->current_image_view_reference().create_info().format, vk::SampleCountFlagBits::e8}, + 1, + avk::memory_usage::device, + avk::image_usage::general_color_attachment + ); + mColorImageView = avk::context().create_image_view(mColorImage); + + mColorAttachment = avk::attachment::declare_dynamic_for(mColorImageView.as_reference(), avk::usage::color(0) + avk::usage::resolve_to(1)); + mResolveAttachment = avk::attachment::declare_dynamic_for(avk::context().main_window()->current_image_view_reference(), avk::usage::unused); + + // Create graphics pipeline for rasterization with the required configuration: + mPipeline = avk::context().create_graphics_pipeline_for( + avk::vertex_shader("shaders/screen_space_tri.vert"), // Add a vertex shader + avk::fragment_shader("shaders/color.frag"), // Add a fragment shader + avk::cfg::viewport_depth_scissors_config::from_framebuffer( + avk::context().main_window()->backbuffer_reference_at_index(0)) // Get scissor and viewport settings from current window backbuffer + .enable_dynamic_viewport(), // But also enable dynamic viewport + avk::cfg::dynamic_rendering::enabled, + mColorAttachment.value() + // mResolveAttachment.value() + ); + + // Get hold of the "ImGui Manager" and add a callback that draws UI elements: + auto imguiManager = avk::current_composition()->element_by_type(); + if (nullptr != imguiManager) { + imguiManager->add_callback([this, r](){ + ImGui::Begin("Info & Settings"); + ImGui::SetWindowPos(ImVec2(1.0f, 1.0f), ImGuiCond_FirstUseEver); + ImGui::Text("%.3f ms/frame", 1000.0f / ImGui::GetIO().Framerate); + ImGui::Text("%.1f FPS", ImGui::GetIO().Framerate); + for(uint32_t i = 0; i < mClearColors.size(); i++) + { + ImGui::ColorEdit4((std::string("Clear color draw ") + std::to_string(i)).c_str(), mClearColors.at(i).data()); + } + const uint32_t minXSize = 2.0 * (1.0f + mBorderThickness); + const uint32_t minYSize = 2.0 * (1.0f + mBorderThickness); + const uint32_t maxXSize = r.x - minXSize; + const uint32_t maxYSize = r.y - minYSize; + ImGui::SliderInt("Draws x split", reinterpret_cast(&mXSplit), minXSize, maxXSize, "%d", ImGuiSliderFlags_AlwaysClamp); + ImGui::SliderInt("Draws y split", reinterpret_cast(&mYSplit), minYSize, maxYSize, "%d", ImGuiSliderFlags_AlwaysClamp); + mXSplit = std::max(std::min(mXSplit, maxXSize), minXSize); + mYSplit = std::max(std::min(mYSplit, maxYSize), minYSize); + ImGui::SliderInt("Border Thickness", reinterpret_cast(&mBorderThickness), 0, 10); + ImGui::Checkbox("Fullscreen viewport", &mFullscreenViewport); + ImGui::End(); + }); + } + } + + void update() override + { + // On Esc pressed, + if (avk::input().key_pressed(avk::key_code::escape) || avk::context().main_window()->should_be_closed()) { + // stop the current composition: + avk::current_composition()->stop(); + } + } + + void render() override + { + auto mainWnd = avk::context().main_window(); + auto inFlightIndex = mainWnd->in_flight_index_for_frame(); + + // Get a command pool to allocate command buffers from: + auto& commandPool = avk::context().get_command_pool_for_single_use_command_buffers(*mQueue); + + // The swap chain provides us with an "image available semaphore" for the current frame. + // Only after the swapchain image has become available, we may start rendering into it. + auto imageAvailableSemaphore = mainWnd->consume_current_image_available_semaphore(); + + // Create a single command buffer: + auto cmdBfr = commandPool->alloc_command_buffers(1u, vk::CommandBufferUsageFlagBits::eOneTimeSubmit); + + avk::image_view swapchainImageView = mainWnd->current_image_view(); + avk::image_t const & swapchainImage = mainWnd->current_image_reference(); + + std::vector renderCommands = {}; + // First we transition the swapchain image into transfer dst layout + renderCommands.emplace_back( + avk::sync::image_memory_barrier(swapchainImage, + // source stage none because it is handled by imageAvailable semaphore + avk::stage::none >> avk::stage::all_transfer, + avk::access::none >> avk::access::transfer_write + // We don't care about the previous contents of the swapchain image (they probably not even defined!) + ).with_layout_transition(avk::layout::undefined >> avk::layout::transfer_dst) + ); + + // Then we clear the swapchain image + vk::Image vulkanSwapchainImage = swapchainImage.handle(); + renderCommands.emplace_back( + avk::command::custom_commands([=](avk::command_buffer_t& cb) { + auto const clearValue = vk::ClearColorValue{0.0f, 0.0f, 0.0f, 1.0f}; + auto const subresourceRange = vk::ImageSubresourceRange( vk::ImageAspectFlagBits::eColor, 0u, 1u, 0u, 1u); + cb.handle().clearColorImage( + vulkanSwapchainImage, + vk::ImageLayout::eTransferDstOptimal, + &clearValue, + 1, + &subresourceRange, + cb.root_ptr()->dispatch_loader_core() + ); + })); + + // Last we transition the swapchain image into color optimal for writing + renderCommands.emplace_back( + avk::sync::image_memory_barrier(swapchainImage, + avk::stage::all_transfer >> avk::stage::color_attachment_output, + avk::access::transfer_write >> avk::access::color_attachment_write + ).with_layout_transition(avk::layout::transfer_dst >> avk::layout::color_attachment_optimal) + ); + + auto const windowResolution = mainWnd->resolution(); + // Set the dynamic viewport only once at the start if we want shared fullscreen viewport for each renderpass + if(mFullscreenViewport) { + auto const currentViewport = vk::Viewport(0.0f, 0.0f, windowResolution.x, windowResolution.y); + renderCommands.emplace_back(avk::command::custom_commands([=](avk::command_buffer_t& cb) { + cb.handle().setViewport(0, 1, ¤tViewport); + })); + } + + // We render the image in four draws - each draw has it's own clear value as well as offset and extent. + // Note that the renderpass extent acts as "clip" on top of the pipeline viewport. + // When we set the fullscreenViewport we thus get a single triangle just drawn in four parts + // Otherwise the viewport is set to be the current extent of the renderpass and we get four separate triangles + for(uint32_t drawIdx = 0; drawIdx < 4; drawIdx++) + { + float xCoord = drawIdx % 2; + float yCoord = drawIdx / 2u; //NOLINT(bugprone-integer-division) Standard way of unpacking 2d y coordinate from 1d encoding + vk::Offset2D const currOffset{ + static_cast(std::min(static_cast(xCoord * mXSplit + xCoord * mBorderThickness), windowResolution.x)), + static_cast(std::min(static_cast(yCoord * mYSplit + yCoord * mBorderThickness), windowResolution.y)) + }; + vk::Extent2D const currExtent{ + static_cast(std::max(static_cast((1 - xCoord) * mXSplit - mBorderThickness + xCoord * (windowResolution.x - mXSplit)), 0)), + static_cast(std::max(static_cast((1 - yCoord) * mYSplit - mBorderThickness + yCoord * (windowResolution.y - mYSplit)), 0)), + }; + if(currExtent.height == 0 || currExtent.width == 0) + { + break; + } + mColorAttachment.value() + .set_clear_color(mClearColors.at(drawIdx)) + .set_load_operation({avk::on_load_behavior::clear, {}}); + // Set the dynamic viewport to be equal to each of the renderpass extent and offsets if don't want shared fullscreen viewport for all of them + renderCommands.emplace_back(avk::command::begin_dynamic_rendering( + {mColorAttachment.value(), mResolveAttachment.value()}, + {mColorImageView, swapchainImageView}, + currOffset, currExtent + )); + renderCommands.emplace_back(avk::command::bind_pipeline(mPipeline.as_reference())); + if(!mFullscreenViewport) + { + auto const currentViewport = vk::Viewport(currOffset.x, currOffset.y, currExtent.width, currExtent.height); + renderCommands.emplace_back(avk::command::custom_commands([=](avk::command_buffer_t& cb) { + cb.handle().setViewport(0, 1, ¤tViewport); + })); + } + renderCommands.emplace_back(avk::command::draw(3u, 1u, 0u, 0u)); + renderCommands.emplace_back(avk::command::end_dynamic_rendering()); + } + + avk::context().record(renderCommands) + .into_command_buffer(cmdBfr[0]) + .then_submit_to(*mQueue) + .waiting_for(imageAvailableSemaphore >> avk::stage::color_attachment_output) + .submit(); + + avk::context().main_window()->handle_lifetime(std::move(cmdBfr[0])); + } + + +private: // v== Member variables ==v + + avk::queue* mQueue; + avk::graphics_pipeline mPipeline; + uint32_t mXSplit; + uint32_t mYSplit; + uint32_t mBorderThickness; + bool mFullscreenViewport; + std::array, 4> mClearColors; + avk::image mColorImage; + avk::image_view mColorImageView; + // subpass_usages have no default constructor... :( + std::optional mColorAttachment; + std::optional mResolveAttachment; + +}; // vertex_buffers_app + +int main() // <== Starting point == +{ + int result = EXIT_FAILURE; + try { + // Create a window and open it + auto mainWnd = avk::context().create_window("Dynamic rendering"); + mainWnd->set_resolution({ 1920, 1080 }); + // mainWnd->enable_resizing(true); + mainWnd->set_presentaton_mode(avk::presentation_mode::mailbox); + mainWnd->set_number_of_concurrent_frames(3u); + mainWnd->open(); + + auto& singleQueue = avk::context().create_queue({}, avk::queue_selection_preference::versatile_queue, mainWnd); + mainWnd->set_queue_family_ownership(singleQueue.family_index()); + mainWnd->set_present_queue(singleQueue); + + // Create an instance of our main "invokee" which contains all the functionality: + auto app = dynamic_rendering_app(singleQueue); + // Create another invokee for drawing the UI with ImGui + auto ui = avk::imgui_manager(singleQueue); + + // Compile all the configuration parameters and the invokees into a "composition": + auto composition = configure_and_compose( + avk::application_name("Auto-Vk-Toolkit Example: Dynamic rendering"), + [](avk::validation_layers& config) { + // config.enable_feature(vk::ValidationFeatureEnableEXT::eSynchronizationValidation); + }, + avk::required_device_extensions() + .add_extension(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME), + // Pass windows: + mainWnd, + // Pass invokees: + app, ui + ); + + // Create an invoker object, which defines the way how invokees/elements are invoked + // (In this case, just sequentially in their execution order): + avk::sequential_invoker invoker; + + // With everything configured, let us start our render loop: + composition.start_render_loop( + // Callback in the case of update: + [&invoker](const std::vector& aToBeInvoked) { + // Call all the update() callbacks: + invoker.invoke_updates(aToBeInvoked); + }, + // Callback in the case of render: + [&invoker](const std::vector& aToBeInvoked) { + // Sync (wait for fences and so) per window BEFORE executing render callbacks + avk::context().execute_for_each_window([](avk::window* wnd) { + wnd->sync_before_render(); + }); + + // Call all the render() callbacks: + invoker.invoke_renders(aToBeInvoked); + + // Render per window: + avk::context().execute_for_each_window([](avk::window* wnd) { + wnd->render_frame(); + }); + } + ); // This is a blocking call, which loops until avk::current_composition()->stop(); has been called (see update()) + + result = EXIT_SUCCESS; + } + catch (avk::logic_error&) {} + catch (avk::runtime_error&) {} + return result; +} diff --git a/examples/framebuffer/source/framebuffer.cpp b/examples/framebuffer/source/framebuffer.cpp index 3cf55e6b..c0cd2a0b 100644 --- a/examples/framebuffer/source/framebuffer.cpp +++ b/examples/framebuffer/source/framebuffer.cpp @@ -191,7 +191,7 @@ class framebuffer_app : public avk::invokee avk::context().record({ // Begin and end one renderpass: - avk::command::render_pass(mPipeline->renderpass_reference(), mOneFramebuffer.as_reference(), { + avk::command::render_pass(mPipeline->renderpass_reference().value(), mOneFramebuffer.as_reference(), { // And within, bind a pipeline and perform an indexed draw call: avk::command::bind_pipeline(mPipeline.as_reference()), avk::command::draw_indexed(mIndexBuffer.as_reference(), mVertexBuffers[inFlightIndex].as_reference()) diff --git a/examples/hello_world/source/hello_world.cpp b/examples/hello_world/source/hello_world.cpp index f211d5e3..32dbe2ae 100644 --- a/examples/hello_world/source/hello_world.cpp +++ b/examples/hello_world/source/hello_world.cpp @@ -111,7 +111,7 @@ class draw_a_triangle_app : public avk::invokee avk::context().record({ // Begin and end one renderpass: - avk::command::render_pass(mPipeline->renderpass_reference(), avk::context().main_window()->current_backbuffer_reference(), { + avk::command::render_pass(mPipeline->renderpass_reference().value(), avk::context().main_window()->current_backbuffer_reference(), { // And within, bind a pipeline and draw three vertices: avk::command::bind_pipeline(mPipeline.as_reference()), avk::command::draw(3u, 1u, 0u, 0u) diff --git a/examples/model_loader/source/model_loader.cpp b/examples/model_loader/source/model_loader.cpp index 3cc2ded7..a43f5fb6 100644 --- a/examples/model_loader/source/model_loader.cpp +++ b/examples/model_loader/source/model_loader.cpp @@ -297,7 +297,7 @@ class model_loader_app : public avk::invokee auto cmdBfr = commandPool->alloc_command_buffer(vk::CommandBufferUsageFlagBits::eOneTimeSubmit); avk::context().record({ - avk::command::render_pass(mPipeline->renderpass_reference(), avk::context().main_window()->current_backbuffer_reference(), { + avk::command::render_pass(mPipeline->renderpass_reference().value(), avk::context().main_window()->current_backbuffer_reference(), { avk::command::bind_pipeline(mPipeline.as_reference()), avk::command::bind_descriptors(mPipeline->layout(), mDescriptorCache->get_or_create_descriptor_sets({ avk::descriptor_binding(0, 0, avk::as_combined_image_samplers(mImageSamplers, avk::layout::shader_read_only_optimal)), diff --git a/examples/multiple_queues/source/multiple_queues.cpp b/examples/multiple_queues/source/multiple_queues.cpp index 76fcba24..b429dea1 100644 --- a/examples/multiple_queues/source/multiple_queues.cpp +++ b/examples/multiple_queues/source/multiple_queues.cpp @@ -194,7 +194,7 @@ class multiple_queues_app : public avk::invokee sync::buffer_memory_barrier(mVertexBuffers[inFlightIndex][1].as_reference(), stage::none + access::none >> stage::vertex_attribute_input + access::vertex_attribute_read) .with_queue_family_ownership_transfer(mTransferQueues[1]->family_index(), mGraphicsQueue->family_index()), - command::render_pass(mPipeline->renderpass_reference(), avk::context().main_window()->current_backbuffer_reference(), { + command::render_pass(mPipeline->renderpass_reference().value(), avk::context().main_window()->current_backbuffer_reference(), { // And within, bind a pipeline and perform an indexed draw call: command::bind_pipeline(mPipeline.as_reference()), // Two draw calls with all the buffer ownerships now transferred to the graphics queue: diff --git a/examples/orca_loader/source/orca_loader.cpp b/examples/orca_loader/source/orca_loader.cpp index bbdfb022..54d0cde2 100644 --- a/examples/orca_loader/source/orca_loader.cpp +++ b/examples/orca_loader/source/orca_loader.cpp @@ -544,7 +544,7 @@ class orca_loader_app : public avk::invokee auto cmdBfr = commandPool->alloc_command_buffer(vk::CommandBufferUsageFlagBits::eOneTimeSubmit); avk::context().record({ - avk::command::render_pass(mPipeline->renderpass_reference(), avk::context().main_window()->current_backbuffer_reference(), { + avk::command::render_pass(mPipeline->renderpass_reference().value(), avk::context().main_window()->current_backbuffer_reference(), { avk::command::bind_pipeline(mPipeline.as_reference()), avk::command::bind_descriptors(mPipeline->layout(), mDescriptorCache->get_or_create_descriptor_sets({ avk::descriptor_binding(0, 5, mViewProjBuffers[ifi]), diff --git a/examples/skinned_meshlets/source/skinned_meshlets.cpp b/examples/skinned_meshlets/source/skinned_meshlets.cpp index 52c2b276..84207bde 100644 --- a/examples/skinned_meshlets/source/skinned_meshlets.cpp +++ b/examples/skinned_meshlets/source/skinned_meshlets.cpp @@ -620,7 +620,7 @@ class skinned_meshlets_app : public avk::invokee return mBoneMatricesBuffersAni[inFlightIndex][std::get(tpl).mBoneMatricesBufferIndex]->fill(std::get(tpl).mBoneMatricesAni.data(), 0); }), - command::render_pass(pipeline->renderpass_reference(), context().main_window()->current_backbuffer_reference(), { + command::render_pass(pipeline->renderpass_reference().value(), context().main_window()->current_backbuffer_reference(), { command::bind_pipeline(pipeline.as_reference()), command::bind_descriptors(pipeline->layout(), mDescriptorCache->get_or_create_descriptor_sets({ descriptor_binding(0, 0, as_combined_image_samplers(mImageSamplers, layout::shader_read_only_optimal)), diff --git a/examples/static_meshlets/source/static_meshlets.cpp b/examples/static_meshlets/source/static_meshlets.cpp index 08229bb3..7d97f04e 100644 --- a/examples/static_meshlets/source/static_meshlets.cpp +++ b/examples/static_meshlets/source/static_meshlets.cpp @@ -465,7 +465,7 @@ mViewProjBuffers[inFlightIndex]->fill(glm::value_ptr(viewProjMat), 0), sync::global_memory_barrier(stage::all_commands >> stage::all_commands, access::memory_write >> access::memory_write | access::memory_read), - command::render_pass(pipeline->renderpass_reference(), context().main_window()->current_backbuffer_reference(), { + command::render_pass(pipeline->renderpass_reference().value(), context().main_window()->current_backbuffer_reference(), { command::bind_pipeline(pipeline.as_reference()), command::bind_descriptors(pipeline->layout(), mDescriptorCache->get_or_create_descriptor_sets({ descriptor_binding(0, 0, as_combined_image_samplers(mImageSamplers, layout::shader_read_only_optimal)), diff --git a/examples/texture_cubemap/source/texture_cubemap.cpp b/examples/texture_cubemap/source/texture_cubemap.cpp index 92d6a52a..65f5f5d9 100644 --- a/examples/texture_cubemap/source/texture_cubemap.cpp +++ b/examples/texture_cubemap/source/texture_cubemap.cpp @@ -263,7 +263,7 @@ class texture_cubemap_app : public avk::invokee avk::context().record({ // Begin and end one renderpass: - avk::command::render_pass(mPipelineSkybox->renderpass_reference(), avk::context().main_window()->current_backbuffer_reference(), avk::command::gather( + avk::command::render_pass(mPipelineSkybox->renderpass_reference().value(), avk::context().main_window()->current_backbuffer_reference(), avk::command::gather( // First, draw the skybox: avk::command::bind_pipeline(mPipelineSkybox.as_reference()), avk::command::bind_descriptors(mPipelineSkybox->layout(), mDescriptorCache->get_or_create_descriptor_sets({ diff --git a/examples/vertex_buffers/source/vertex_buffers.cpp b/examples/vertex_buffers/source/vertex_buffers.cpp index f79b3e1d..558d8244 100644 --- a/examples/vertex_buffers/source/vertex_buffers.cpp +++ b/examples/vertex_buffers/source/vertex_buffers.cpp @@ -166,7 +166,7 @@ class vertex_buffers_app : public avk::invokee // avk::sync::buffer_memory_barrier(mVertexBuffers[inFlightIndex].as_reference(), avk::stage::auto_stage >> avk::stage::vertex_attribute_input, avk::access:: auto_access >> avk::access::vertex_attribute_read), // Begin and end one renderpass: - avk::command::render_pass(mPipeline->renderpass_reference(), avk::context().main_window()->current_backbuffer_reference(), { + avk::command::render_pass(mPipeline->renderpass_reference().value(), avk::context().main_window()->current_backbuffer_reference(), { // And within, bind a pipeline and perform an indexed draw call: avk::command::bind_pipeline(mPipeline.as_reference()), avk::command::draw_indexed(mIndexBuffer.as_reference(), mVertexBuffers[inFlightIndex].as_reference()) diff --git a/visual_studio/auto_vk_toolkit.sln b/visual_studio/auto_vk_toolkit.sln index d506a2d0..ee952c27 100644 --- a/visual_studio/auto_vk_toolkit.sln +++ b/visual_studio/auto_vk_toolkit.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.28531.58 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34221.43 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "auto_vk_toolkit", "auto_vk_toolkit\auto_vk_toolkit.vcxproj", "{602F842F-50C1-466D-8696-1707937D8AB9}" EndProject @@ -46,6 +46,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multiple_queues", "examples EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "present_from_compute", "examples\present_from_compute\present_from_compute.vcxproj", "{14DC267E-090F-442E-82FB-31A16759ECDC}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dynamic_rendering", "examples\dynamic_rendering\dynamic_rendering.vcxproj", "{C9892273-E97F-49F5-8A0D-96278284EAFF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug_Vulkan|x64 = Debug_Vulkan|x64 @@ -149,6 +151,12 @@ Global {14DC267E-090F-442E-82FB-31A16759ECDC}.Publish_Vulkan|x64.Build.0 = Publish_Vulkan|x64 {14DC267E-090F-442E-82FB-31A16759ECDC}.Release_Vulkan|x64.ActiveCfg = Release_Vulkan|x64 {14DC267E-090F-442E-82FB-31A16759ECDC}.Release_Vulkan|x64.Build.0 = Release_Vulkan|x64 + {C9892273-E97F-49F5-8A0D-96278284EAFF}.Debug_Vulkan|x64.ActiveCfg = Debug_Vulkan|x64 + {C9892273-E97F-49F5-8A0D-96278284EAFF}.Debug_Vulkan|x64.Build.0 = Debug_Vulkan|x64 + {C9892273-E97F-49F5-8A0D-96278284EAFF}.Publish_Vulkan|x64.ActiveCfg = Publish_Vulkan|x64 + {C9892273-E97F-49F5-8A0D-96278284EAFF}.Publish_Vulkan|x64.Build.0 = Publish_Vulkan|x64 + {C9892273-E97F-49F5-8A0D-96278284EAFF}.Release_Vulkan|x64.ActiveCfg = Release_Vulkan|x64 + {C9892273-E97F-49F5-8A0D-96278284EAFF}.Release_Vulkan|x64.Build.0 = Release_Vulkan|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -174,6 +182,7 @@ Global {295E18F0-C25C-4864-9D61-4A7F6EE13EFB} = {B883882B-129A-4528-86E3-68638929D9EC} {3CD62905-610C-4EA1-A378-E1DFE6A6871C} = {08A10CAA-9B1B-41DB-9EB5-8547AC3077EA} {14DC267E-090F-442E-82FB-31A16759ECDC} = {E796A880-48FF-48FF-A7F0-A3A522223061} + {C9892273-E97F-49F5-8A0D-96278284EAFF} = {08A10CAA-9B1B-41DB-9EB5-8547AC3077EA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A8961D43-F08D-46E3-B3BB-29BA8AA39C3E} diff --git a/visual_studio/examples/dynamic_rendering/cg_stdafx.cpp b/visual_studio/examples/dynamic_rendering/cg_stdafx.cpp new file mode 100644 index 00000000..75870fb8 --- /dev/null +++ b/visual_studio/examples/dynamic_rendering/cg_stdafx.cpp @@ -0,0 +1,8 @@ +// cg_stdafx.cpp : source file that includes just the standard includes +// cg_stdafx.pch will be the pre-compiled header +// cg_stdafx.obj will contain the pre-compiled type information + +#include "cg_stdafx.hpp" + +// TODO: reference any additional headers you need in cg_stdafx.hpp +// and not in this file diff --git a/visual_studio/examples/dynamic_rendering/cg_stdafx.hpp b/visual_studio/examples/dynamic_rendering/cg_stdafx.hpp new file mode 100644 index 00000000..de483fc1 --- /dev/null +++ b/visual_studio/examples/dynamic_rendering/cg_stdafx.hpp @@ -0,0 +1,11 @@ +// cg_stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// +#pragma once + +#include "cg_targetver.hpp" + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include "auto_vk_toolkit.hpp" diff --git a/visual_studio/examples/dynamic_rendering/cg_targetver.hpp b/visual_studio/examples/dynamic_rendering/cg_targetver.hpp new file mode 100644 index 00000000..87c0086d --- /dev/null +++ b/visual_studio/examples/dynamic_rendering/cg_targetver.hpp @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/visual_studio/examples/dynamic_rendering/dynamic_rendering.vcxproj b/visual_studio/examples/dynamic_rendering/dynamic_rendering.vcxproj new file mode 100644 index 00000000..7088bf93 --- /dev/null +++ b/visual_studio/examples/dynamic_rendering/dynamic_rendering.vcxproj @@ -0,0 +1,189 @@ + + + + + Debug_Vulkan + x64 + + + Publish_Vulkan + x64 + + + Release_Vulkan + x64 + + + + + + Create + Create + Create + + + + + + + + + + + + + {602f842f-50c1-466d-8696-1707937d8ab9} + + + + 15.0 + {C9892273-E97F-49F5-8A0D-96278284EAFF} + Win32Proj + dynamic_rendering + 10.0 + dynamic_rendering + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + $(ProjectDir)bin\$(Configuration)_$(Platform)\ + $(ProjectDir)temp\intermediate\$(Configuration)_$(Platform)\ + Build + + + false + $(ProjectDir)bin\$(Configuration)_$(Platform)\executable\ + $(ProjectDir)temp\intermediate\$(Configuration)_$(Platform)\ + Build + + + true + $(ProjectDir)bin\$(Configuration)_$(Platform)\ + $(ProjectDir)temp\intermediate\$(Configuration)_$(Platform)\ + Build + + + + Use + Level3 + MaxSpeed + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpplatest + cg_stdafx.hpp + 4715 + cg_stdafx.hpp + + + Console + true + true + true + + + powershell.exe -ExecutionPolicy Bypass -File "$(ToolsBin)invoke_post_build_helper.ps1" -msbuild "$(MsBuildToolsPath)" -configuration "$(Configuration)" -framework "$(FrameworkRoot)\" -platform "$(Platform)" -vcxproj "$(ProjectPath)" -filters "$(ProjectPath).filters" -output "$(OutputPath)\" -executable "$(TargetPath)" -external "$(ExternalRoot)\" + some-non-existant-file-to-always-run-the-custom-build-step.txt;%(Outputs) + + + + + Use + Level3 + MaxSpeed + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpplatest + cg_stdafx.hpp + 4715 + cg_stdafx.hpp + + + Console + true + true + true + + + powershell.exe -ExecutionPolicy Bypass -File "$(ToolsBin)invoke_post_build_helper.ps1" -msbuild "$(MsBuildToolsPath)" -configuration "$(Configuration)" -framework "$(FrameworkRoot)\" -platform "$(Platform)" -vcxproj "$(ProjectPath)" -filters "$(ProjectPath).filters" -output "$(OutputPath)\" -executable "$(TargetPath)" -external "$(ExternalRoot)\" + some-non-existant-file-to-always-run-the-custom-build-step.txt;%(Outputs) + + + + + Use + Level3 + Disabled + false + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp20 + cg_stdafx.hpp + 4715 + cg_stdafx.hpp + + + Console + true + + + powershell.exe -ExecutionPolicy Bypass -File "$(ToolsBin)invoke_post_build_helper.ps1" -msbuild "$(MsBuildToolsPath)" -configuration "$(Configuration)" -framework "$(FrameworkRoot)\" -platform "$(Platform)" -vcxproj "$(ProjectPath)" -filters "$(ProjectPath).filters" -output "$(OutputPath)\" -executable "$(TargetPath)" -external "$(ExternalRoot)\" + some-non-existant-file-to-always-run-the-custom-build-step.txt;%(Outputs) + + + + + + \ No newline at end of file diff --git a/visual_studio/examples/dynamic_rendering/dynamic_rendering.vcxproj.filters b/visual_studio/examples/dynamic_rendering/dynamic_rendering.vcxproj.filters new file mode 100644 index 00000000..426160a2 --- /dev/null +++ b/visual_studio/examples/dynamic_rendering/dynamic_rendering.vcxproj.filters @@ -0,0 +1,37 @@ + + + + + {24240a51-8fdb-478f-8c1c-27cbca7adc3f} + False + + + {1d345cf5-0451-42e0-83a8-6a3f5a7203ca} + + + {01a7b8ad-6f1e-486f-b173-7f12ab65fa3d} + + + + + precompiled_headers + + + + + + precompiled_headers + + + precompiled_headers + + + + + shaders + + + shaders + + + \ No newline at end of file diff --git a/visual_studio/examples/dynamic_rendering/dynamic_rendering.vcxproj.user b/visual_studio/examples/dynamic_rendering/dynamic_rendering.vcxproj.user new file mode 100644 index 00000000..382932fd --- /dev/null +++ b/visual_studio/examples/dynamic_rendering/dynamic_rendering.vcxproj.user @@ -0,0 +1,15 @@ + + + + $(OutputPath) + WindowsLocalDebugger + + + $(OutputPath) + WindowsLocalDebugger + + + $(OutputPath) + WindowsLocalDebugger + + \ No newline at end of file