Files
test2/source/blender/gpu/vulkan/vk_context.cc

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

565 lines
19 KiB
C++
Raw Normal View History

/* SPDX-FileCopyrightText: 2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup gpu
*/
#include "DNA_userdef_types.h"
#include "GPU_debug.hh"
#include "gpu_capabilities_private.hh"
#include "vk_backend.hh"
#include "vk_context.hh"
#include "vk_debug.hh"
#include "vk_framebuffer.hh"
Vulkan: Initial Graphics Pipeline Initial graphic pipeline targeting. The goal of this PR is to have an initial graphics pipeline with missing features. It should help identifying areas that requires engineering. Current state is that developers of the GPU module can help with the many smaller pieces that needs to be engineered in order to get it working. It is not intended for users or developers from other modules, but your welcome to learn and give feedback on the code and engineering part. We do expect that large parts of the code still needs to be re-engineered into a more future-proof implementation. **Some highlights**: - In Vulkan the state is kept in the pipeline. Therefore the state is tracked per pipeline. In the near future this could be used as a cache. More research is needed against the default pipeline cache that vulkan already provides. - This PR is based on the work that Kazashi Yoshioka already did. And include work from him in the next areas - Vertex attributes - Vertex data conversions - Pipeline state - Immediate support working. - This PR modifies the VKCommandBuffer to keep track of the framebuffer and its binding state(render pass). Some Vulkan commands require no render pass to be active, other require a render pass. As the order of our commands on API level can not be separated this PR introduces a state engine to keep track of the current state and desired state. This is a temporary solution, the final solution will be proposed when we have a pixel on the screen. At that time I expect that we can design a command encoder that supports all the cases we need. **Notices**: - This branch works on NVIDIA GPUs and has been validated on a Linux system. AMD is known not to work (stalls) and Intel GPUs have not been tested at all. Windows might work but hasn't been validated yet. - The graphics pipeline is implemented with pixels in mind, not with performance. Currently when a draw call is scheduled it is flushed and waited until it is finished drawing, before other draw calls can be scheduled. We expected the performance to be worse that it actually is, but we expect huge performance gains in the future. - Any advanced drawing (that is used by the image editor, compositor or 3d viewport) isn't implemented and might crash when used. - Using multiple windows or resizing of window isn't supported and will stall the system. Pull Request: https://projects.blender.org/blender/blender/pulls/106224
2023-05-11 13:01:56 +02:00
#include "vk_immediate.hh"
#include "vk_shader.hh"
#include "vk_shader_interface.hh"
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
#include "vk_state_manager.hh"
Vulkan: Initial Graphics Pipeline Initial graphic pipeline targeting. The goal of this PR is to have an initial graphics pipeline with missing features. It should help identifying areas that requires engineering. Current state is that developers of the GPU module can help with the many smaller pieces that needs to be engineered in order to get it working. It is not intended for users or developers from other modules, but your welcome to learn and give feedback on the code and engineering part. We do expect that large parts of the code still needs to be re-engineered into a more future-proof implementation. **Some highlights**: - In Vulkan the state is kept in the pipeline. Therefore the state is tracked per pipeline. In the near future this could be used as a cache. More research is needed against the default pipeline cache that vulkan already provides. - This PR is based on the work that Kazashi Yoshioka already did. And include work from him in the next areas - Vertex attributes - Vertex data conversions - Pipeline state - Immediate support working. - This PR modifies the VKCommandBuffer to keep track of the framebuffer and its binding state(render pass). Some Vulkan commands require no render pass to be active, other require a render pass. As the order of our commands on API level can not be separated this PR introduces a state engine to keep track of the current state and desired state. This is a temporary solution, the final solution will be proposed when we have a pixel on the screen. At that time I expect that we can design a command encoder that supports all the cases we need. **Notices**: - This branch works on NVIDIA GPUs and has been validated on a Linux system. AMD is known not to work (stalls) and Intel GPUs have not been tested at all. Windows might work but hasn't been validated yet. - The graphics pipeline is implemented with pixels in mind, not with performance. Currently when a draw call is scheduled it is flushed and waited until it is finished drawing, before other draw calls can be scheduled. We expected the performance to be worse that it actually is, but we expect huge performance gains in the future. - Any advanced drawing (that is used by the image editor, compositor or 3d viewport) isn't implemented and might crash when used. - Using multiple windows or resizing of window isn't supported and will stall the system. Pull Request: https://projects.blender.org/blender/blender/pulls/106224
2023-05-11 13:01:56 +02:00
#include "vk_texture.hh"
#include "GHOST_C-api.h"
namespace blender::gpu {
Vulkan: Device command builder This PR implements a new the threading model for building render graphs based on tests performed last month. For out workload multithreaded command building will block in the driver or device. So better to use a single thread for command building. Details of the internal working is documented at https://developer.blender.org/docs/features/gpu/vulkan/render_graph/ - When a context is activated on a thread the context asks for a render graph it can use by calling `VKDevice::render_graph_new`. - Parts of the GPU backend that requires GPU commands will add a specific render graph node to the render graph. The nodes also contains a reference to all resources it needs including the access it needs and the image layout. - When the context is flushed the render graph is submitted to the device by calling `VKDevice::render_graph_submit`. - The device puts the render graph in `VKDevice::submission_pool`. - There is a single background thread that gets the next render graph to send to the GPU (`VKDevice::submission_runner`). - Reorder the commands of the render graph to comply with Vulkan specific command order rules and reducing possible bottlenecks. (`VKScheduler`) - Generate the required barriers `VKCommandBuilder::groups_extract_barriers`. This is a separate step to reduce resource locking giving other threads access to the resource states when they are building the render graph nodes. - GPU commands and pipeline barriers are recorded to a VkCommandBuffer. (`VKCommandBuilder::record_commands`) - When completed the command buffer can be submitted to the device queue. `vkQueueSubmit` - Render graphs that have been submitted can be reused by a next thread. This is done by pushing the render graph to the `VKDevice::unused_render_graphs` queue. Pull Request: https://projects.blender.org/blender/blender/pulls/132681
2025-01-27 08:55:23 +01:00
VKContext::VKContext(void *ghost_window, void *ghost_context)
{
ghost_window_ = ghost_window;
Vulkan: Initial Compute Shaders support This patch adds initial support for compute shaders to the vulkan backend. As the development is oriented to the test- cases we have the implementation is limited to what is used there. It has been validated that with this patch that the following test cases are running as expected - `GPUVulkanTest.gpu_shader_compute_vbo` - `GPUVulkanTest.gpu_shader_compute_ibo` - `GPUVulkanTest.gpu_shader_compute_ssbo` - `GPUVulkanTest.gpu_storage_buffer_create_update_read` - `GPUVulkanTest.gpu_shader_compute_2d` This patch includes: - Allocating VkBuffer on device. - Uploading data from CPU to VkBuffer. - Binding VkBuffer as SSBO to a compute shader. - Execute compute shader and altering VkBuffer. - Download the VkBuffer to CPU ram. - Validate that it worked. - Use device only vertex buffer as SSBO - Use device only index buffer as SSBO - Use device only image buffers GHOST API has been changed as the original design was created before we even had support for compute shaders in blender. The function `GHOST_getVulkanBackbuffer` has been separated to retrieve the command buffer without a backbuffer (`GHOST_getVulkanCommandBuffer`). In order to do correct command buffer processing we needed access to the queue owned by GHOST. This is returned as part of the `GHOST_getVulkanHandles` function. Open topics (not considered part of this patch) - Memory barriers & command buffer encoding - Indirect compute dispatching - Rest of the test cases - Data conversions when requested data format is different than on device. - GPUVulkanTest.gpu_shader_compute_1d is supported on AMD devices. NVIDIA doesn't seem to support 1d textures. Pull-request: #104518
2023-02-21 15:03:12 +01:00
ghost_context_ = ghost_context;
state_manager = new VKStateManager();
imm = new VKImmediate();
back_left = new VKFrameBuffer("back_left");
front_left = new VKFrameBuffer("front_left");
active_fb = back_left;
}
Vulkan: Initial Graphics Pipeline Initial graphic pipeline targeting. The goal of this PR is to have an initial graphics pipeline with missing features. It should help identifying areas that requires engineering. Current state is that developers of the GPU module can help with the many smaller pieces that needs to be engineered in order to get it working. It is not intended for users or developers from other modules, but your welcome to learn and give feedback on the code and engineering part. We do expect that large parts of the code still needs to be re-engineered into a more future-proof implementation. **Some highlights**: - In Vulkan the state is kept in the pipeline. Therefore the state is tracked per pipeline. In the near future this could be used as a cache. More research is needed against the default pipeline cache that vulkan already provides. - This PR is based on the work that Kazashi Yoshioka already did. And include work from him in the next areas - Vertex attributes - Vertex data conversions - Pipeline state - Immediate support working. - This PR modifies the VKCommandBuffer to keep track of the framebuffer and its binding state(render pass). Some Vulkan commands require no render pass to be active, other require a render pass. As the order of our commands on API level can not be separated this PR introduces a state engine to keep track of the current state and desired state. This is a temporary solution, the final solution will be proposed when we have a pixel on the screen. At that time I expect that we can design a command encoder that supports all the cases we need. **Notices**: - This branch works on NVIDIA GPUs and has been validated on a Linux system. AMD is known not to work (stalls) and Intel GPUs have not been tested at all. Windows might work but hasn't been validated yet. - The graphics pipeline is implemented with pixels in mind, not with performance. Currently when a draw call is scheduled it is flushed and waited until it is finished drawing, before other draw calls can be scheduled. We expected the performance to be worse that it actually is, but we expect huge performance gains in the future. - Any advanced drawing (that is used by the image editor, compositor or 3d viewport) isn't implemented and might crash when used. - Using multiple windows or resizing of window isn't supported and will stall the system. Pull Request: https://projects.blender.org/blender/blender/pulls/106224
2023-05-11 13:01:56 +02:00
VKContext::~VKContext()
{
Vulkan: Rewrite GHOST_ContextVK This is a rewrite of GHOST_ContextVK to align with Metal backend as described in #111389 - solution 3 with the adaptation that GHOST is still responsible for presenting the swap chain image and a post callback is still needed in case the swapchain is recreated. This PR also includes some smaller improvements in stability. Technical documentation: https://developer.blender.org/docs/eevee_and_viewport/gpu/vulkan/swap_chain/ * Renderpasses and framebuffers are not owned anymore by GHOST_ContextVK * VKFramebuffer doesn't contain a swap chain image. * Swapchain images can only be used as a blit destination or present source. Not as an attachment. * GHOST_ContextVK::swapBuffers would call a callback with the image the GPU module needs to blit the results to. * Clearing of depth/stencil attachments when no depth write state is set. * Enable VK_KHR_maintenance4 to relax the stage interface mapping. * Removes most vulkan validation warnings/errors. * Detection of frame buffer changes that needs to be applied before performing a command requiring render pass (draw/clear attachment) **Benefits** * Late retrieval of a swap chain image results in better overall performance as Blender doesn't need to wait until the image is presented on the screen. * Easier API and clearer state (transitions) * More control over Image layouts and command buffer states. (Better alignment with Vulkan API) Pull Request: https://projects.blender.org/blender/blender/pulls/111473
2023-08-29 15:05:08 +02:00
if (surface_texture_) {
back_left->attachment_remove(GPU_FB_COLOR_ATTACHMENT0);
front_left->attachment_remove(GPU_FB_COLOR_ATTACHMENT0);
Vulkan: Rewrite GHOST_ContextVK This is a rewrite of GHOST_ContextVK to align with Metal backend as described in #111389 - solution 3 with the adaptation that GHOST is still responsible for presenting the swap chain image and a post callback is still needed in case the swapchain is recreated. This PR also includes some smaller improvements in stability. Technical documentation: https://developer.blender.org/docs/eevee_and_viewport/gpu/vulkan/swap_chain/ * Renderpasses and framebuffers are not owned anymore by GHOST_ContextVK * VKFramebuffer doesn't contain a swap chain image. * Swapchain images can only be used as a blit destination or present source. Not as an attachment. * GHOST_ContextVK::swapBuffers would call a callback with the image the GPU module needs to blit the results to. * Clearing of depth/stencil attachments when no depth write state is set. * Enable VK_KHR_maintenance4 to relax the stage interface mapping. * Removes most vulkan validation warnings/errors. * Detection of frame buffer changes that needs to be applied before performing a command requiring render pass (draw/clear attachment) **Benefits** * Late retrieval of a swap chain image results in better overall performance as Blender doesn't need to wait until the image is presented on the screen. * Easier API and clearer state (transitions) * More control over Image layouts and command buffer states. (Better alignment with Vulkan API) Pull Request: https://projects.blender.org/blender/blender/pulls/111473
2023-08-29 15:05:08 +02:00
GPU_texture_free(surface_texture_);
surface_texture_ = nullptr;
}
free_resources();
delete imm;
imm = nullptr;
VKDevice &device = VKBackend::get().device;
device.context_unregister(*this);
this->process_frame_timings();
Vulkan: Initial Graphics Pipeline Initial graphic pipeline targeting. The goal of this PR is to have an initial graphics pipeline with missing features. It should help identifying areas that requires engineering. Current state is that developers of the GPU module can help with the many smaller pieces that needs to be engineered in order to get it working. It is not intended for users or developers from other modules, but your welcome to learn and give feedback on the code and engineering part. We do expect that large parts of the code still needs to be re-engineered into a more future-proof implementation. **Some highlights**: - In Vulkan the state is kept in the pipeline. Therefore the state is tracked per pipeline. In the near future this could be used as a cache. More research is needed against the default pipeline cache that vulkan already provides. - This PR is based on the work that Kazashi Yoshioka already did. And include work from him in the next areas - Vertex attributes - Vertex data conversions - Pipeline state - Immediate support working. - This PR modifies the VKCommandBuffer to keep track of the framebuffer and its binding state(render pass). Some Vulkan commands require no render pass to be active, other require a render pass. As the order of our commands on API level can not be separated this PR introduces a state engine to keep track of the current state and desired state. This is a temporary solution, the final solution will be proposed when we have a pixel on the screen. At that time I expect that we can design a command encoder that supports all the cases we need. **Notices**: - This branch works on NVIDIA GPUs and has been validated on a Linux system. AMD is known not to work (stalls) and Intel GPUs have not been tested at all. Windows might work but hasn't been validated yet. - The graphics pipeline is implemented with pixels in mind, not with performance. Currently when a draw call is scheduled it is flushed and waited until it is finished drawing, before other draw calls can be scheduled. We expected the performance to be worse that it actually is, but we expect huge performance gains in the future. - Any advanced drawing (that is used by the image editor, compositor or 3d viewport) isn't implemented and might crash when used. - Using multiple windows or resizing of window isn't supported and will stall the system. Pull Request: https://projects.blender.org/blender/blender/pulls/106224
2023-05-11 13:01:56 +02:00
}
void VKContext::sync_backbuffer()
{
Vulkan: Rewrite GHOST_ContextVK This is a rewrite of GHOST_ContextVK to align with Metal backend as described in #111389 - solution 3 with the adaptation that GHOST is still responsible for presenting the swap chain image and a post callback is still needed in case the swapchain is recreated. This PR also includes some smaller improvements in stability. Technical documentation: https://developer.blender.org/docs/eevee_and_viewport/gpu/vulkan/swap_chain/ * Renderpasses and framebuffers are not owned anymore by GHOST_ContextVK * VKFramebuffer doesn't contain a swap chain image. * Swapchain images can only be used as a blit destination or present source. Not as an attachment. * GHOST_ContextVK::swapBuffers would call a callback with the image the GPU module needs to blit the results to. * Clearing of depth/stencil attachments when no depth write state is set. * Enable VK_KHR_maintenance4 to relax the stage interface mapping. * Removes most vulkan validation warnings/errors. * Detection of frame buffer changes that needs to be applied before performing a command requiring render pass (draw/clear attachment) **Benefits** * Late retrieval of a swap chain image results in better overall performance as Blender doesn't need to wait until the image is presented on the screen. * Easier API and clearer state (transitions) * More control over Image layouts and command buffer states. (Better alignment with Vulkan API) Pull Request: https://projects.blender.org/blender/blender/pulls/111473
2023-08-29 15:05:08 +02:00
if (ghost_window_) {
GHOST_VulkanSwapChainData swap_chain_data = {};
GHOST_GetVulkanSwapChainFormat((GHOST_WindowHandle)ghost_window_, &swap_chain_data);
const bool reset_framebuffer = swap_chain_format_.format !=
swap_chain_data.surface_format.format ||
swap_chain_format_.colorSpace !=
swap_chain_data.surface_format.colorSpace ||
Vulkan: Rewrite GHOST_ContextVK This is a rewrite of GHOST_ContextVK to align with Metal backend as described in #111389 - solution 3 with the adaptation that GHOST is still responsible for presenting the swap chain image and a post callback is still needed in case the swapchain is recreated. This PR also includes some smaller improvements in stability. Technical documentation: https://developer.blender.org/docs/eevee_and_viewport/gpu/vulkan/swap_chain/ * Renderpasses and framebuffers are not owned anymore by GHOST_ContextVK * VKFramebuffer doesn't contain a swap chain image. * Swapchain images can only be used as a blit destination or present source. Not as an attachment. * GHOST_ContextVK::swapBuffers would call a callback with the image the GPU module needs to blit the results to. * Clearing of depth/stencil attachments when no depth write state is set. * Enable VK_KHR_maintenance4 to relax the stage interface mapping. * Removes most vulkan validation warnings/errors. * Detection of frame buffer changes that needs to be applied before performing a command requiring render pass (draw/clear attachment) **Benefits** * Late retrieval of a swap chain image results in better overall performance as Blender doesn't need to wait until the image is presented on the screen. * Easier API and clearer state (transitions) * More control over Image layouts and command buffer states. (Better alignment with Vulkan API) Pull Request: https://projects.blender.org/blender/blender/pulls/111473
2023-08-29 15:05:08 +02:00
vk_extent_.width != swap_chain_data.extent.width ||
vk_extent_.height != swap_chain_data.extent.height;
if (reset_framebuffer) {
if (has_active_framebuffer()) {
deactivate_framebuffer();
}
if (surface_texture_) {
GPU_texture_free(surface_texture_);
surface_texture_ = nullptr;
}
vk_extent_ = swap_chain_data.extent;
vk_extent_.width = max_uu(vk_extent_.width, 1u);
vk_extent_.height = max_uu(vk_extent_.height, 1u);
surface_texture_ = GPU_texture_create_2d(
"back-left",
vk_extent_.width,
vk_extent_.height,
1,
to_gpu_format(swap_chain_data.surface_format.format),
GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_SHADER_READ,
nullptr);
Vulkan: Rewrite GHOST_ContextVK This is a rewrite of GHOST_ContextVK to align with Metal backend as described in #111389 - solution 3 with the adaptation that GHOST is still responsible for presenting the swap chain image and a post callback is still needed in case the swapchain is recreated. This PR also includes some smaller improvements in stability. Technical documentation: https://developer.blender.org/docs/eevee_and_viewport/gpu/vulkan/swap_chain/ * Renderpasses and framebuffers are not owned anymore by GHOST_ContextVK * VKFramebuffer doesn't contain a swap chain image. * Swapchain images can only be used as a blit destination or present source. Not as an attachment. * GHOST_ContextVK::swapBuffers would call a callback with the image the GPU module needs to blit the results to. * Clearing of depth/stencil attachments when no depth write state is set. * Enable VK_KHR_maintenance4 to relax the stage interface mapping. * Removes most vulkan validation warnings/errors. * Detection of frame buffer changes that needs to be applied before performing a command requiring render pass (draw/clear attachment) **Benefits** * Late retrieval of a swap chain image results in better overall performance as Blender doesn't need to wait until the image is presented on the screen. * Easier API and clearer state (transitions) * More control over Image layouts and command buffer states. (Better alignment with Vulkan API) Pull Request: https://projects.blender.org/blender/blender/pulls/111473
2023-08-29 15:05:08 +02:00
back_left->attachment_set(GPU_FB_COLOR_ATTACHMENT0,
GPU_ATTACHMENT_TEXTURE(surface_texture_));
front_left->attachment_set(GPU_FB_COLOR_ATTACHMENT0,
GPU_ATTACHMENT_TEXTURE(surface_texture_));
Vulkan: Rewrite GHOST_ContextVK This is a rewrite of GHOST_ContextVK to align with Metal backend as described in #111389 - solution 3 with the adaptation that GHOST is still responsible for presenting the swap chain image and a post callback is still needed in case the swapchain is recreated. This PR also includes some smaller improvements in stability. Technical documentation: https://developer.blender.org/docs/eevee_and_viewport/gpu/vulkan/swap_chain/ * Renderpasses and framebuffers are not owned anymore by GHOST_ContextVK * VKFramebuffer doesn't contain a swap chain image. * Swapchain images can only be used as a blit destination or present source. Not as an attachment. * GHOST_ContextVK::swapBuffers would call a callback with the image the GPU module needs to blit the results to. * Clearing of depth/stencil attachments when no depth write state is set. * Enable VK_KHR_maintenance4 to relax the stage interface mapping. * Removes most vulkan validation warnings/errors. * Detection of frame buffer changes that needs to be applied before performing a command requiring render pass (draw/clear attachment) **Benefits** * Late retrieval of a swap chain image results in better overall performance as Blender doesn't need to wait until the image is presented on the screen. * Easier API and clearer state (transitions) * More control over Image layouts and command buffer states. (Better alignment with Vulkan API) Pull Request: https://projects.blender.org/blender/blender/pulls/111473
2023-08-29 15:05:08 +02:00
back_left->bind(false);
swap_chain_format_ = swap_chain_data.surface_format;
GCaps.hdr_viewport_support = (swap_chain_format_.format == VK_FORMAT_R16G16B16A16_SFLOAT) &&
ELEM(swap_chain_format_.colorSpace,
VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT,
VK_COLOR_SPACE_SRGB_NONLINEAR_KHR);
Vulkan: Rewrite GHOST_ContextVK This is a rewrite of GHOST_ContextVK to align with Metal backend as described in #111389 - solution 3 with the adaptation that GHOST is still responsible for presenting the swap chain image and a post callback is still needed in case the swapchain is recreated. This PR also includes some smaller improvements in stability. Technical documentation: https://developer.blender.org/docs/eevee_and_viewport/gpu/vulkan/swap_chain/ * Renderpasses and framebuffers are not owned anymore by GHOST_ContextVK * VKFramebuffer doesn't contain a swap chain image. * Swapchain images can only be used as a blit destination or present source. Not as an attachment. * GHOST_ContextVK::swapBuffers would call a callback with the image the GPU module needs to blit the results to. * Clearing of depth/stencil attachments when no depth write state is set. * Enable VK_KHR_maintenance4 to relax the stage interface mapping. * Removes most vulkan validation warnings/errors. * Detection of frame buffer changes that needs to be applied before performing a command requiring render pass (draw/clear attachment) **Benefits** * Late retrieval of a swap chain image results in better overall performance as Blender doesn't need to wait until the image is presented on the screen. * Easier API and clearer state (transitions) * More control over Image layouts and command buffer states. (Better alignment with Vulkan API) Pull Request: https://projects.blender.org/blender/blender/pulls/111473
2023-08-29 15:05:08 +02:00
}
}
}
void VKContext::activate()
{
/* Make sure no other context is already bound to this thread. */
BLI_assert(is_active_ == false);
VKDevice &device = VKBackend::get().device;
VKThreadData &thread_data = device.current_thread_data();
thread_data_ = std::reference_wrapper<VKThreadData>(thread_data);
Vulkan: Device command builder This PR implements a new the threading model for building render graphs based on tests performed last month. For out workload multithreaded command building will block in the driver or device. So better to use a single thread for command building. Details of the internal working is documented at https://developer.blender.org/docs/features/gpu/vulkan/render_graph/ - When a context is activated on a thread the context asks for a render graph it can use by calling `VKDevice::render_graph_new`. - Parts of the GPU backend that requires GPU commands will add a specific render graph node to the render graph. The nodes also contains a reference to all resources it needs including the access it needs and the image layout. - When the context is flushed the render graph is submitted to the device by calling `VKDevice::render_graph_submit`. - The device puts the render graph in `VKDevice::submission_pool`. - There is a single background thread that gets the next render graph to send to the GPU (`VKDevice::submission_runner`). - Reorder the commands of the render graph to comply with Vulkan specific command order rules and reducing possible bottlenecks. (`VKScheduler`) - Generate the required barriers `VKCommandBuilder::groups_extract_barriers`. This is a separate step to reduce resource locking giving other threads access to the resource states when they are building the render graph nodes. - GPU commands and pipeline barriers are recorded to a VkCommandBuffer. (`VKCommandBuilder::record_commands`) - When completed the command buffer can be submitted to the device queue. `vkQueueSubmit` - Render graphs that have been submitted can be reused by a next thread. This is done by pushing the render graph to the `VKDevice::unused_render_graphs` queue. Pull Request: https://projects.blender.org/blender/blender/pulls/132681
2025-01-27 08:55:23 +01:00
if (!render_graph_.has_value()) {
render_graph_ = std::reference_wrapper<render_graph::VKRenderGraph>(
*device.render_graph_new());
/* Recreate the debug group stack for the new graph.
* Note: there is no associated `debug_group_end` as the graph groups
* are implicitly closed on submission. */
Vulkan: Device command builder This PR implements a new the threading model for building render graphs based on tests performed last month. For out workload multithreaded command building will block in the driver or device. So better to use a single thread for command building. Details of the internal working is documented at https://developer.blender.org/docs/features/gpu/vulkan/render_graph/ - When a context is activated on a thread the context asks for a render graph it can use by calling `VKDevice::render_graph_new`. - Parts of the GPU backend that requires GPU commands will add a specific render graph node to the render graph. The nodes also contains a reference to all resources it needs including the access it needs and the image layout. - When the context is flushed the render graph is submitted to the device by calling `VKDevice::render_graph_submit`. - The device puts the render graph in `VKDevice::submission_pool`. - There is a single background thread that gets the next render graph to send to the GPU (`VKDevice::submission_runner`). - Reorder the commands of the render graph to comply with Vulkan specific command order rules and reducing possible bottlenecks. (`VKScheduler`) - Generate the required barriers `VKCommandBuilder::groups_extract_barriers`. This is a separate step to reduce resource locking giving other threads access to the resource states when they are building the render graph nodes. - GPU commands and pipeline barriers are recorded to a VkCommandBuffer. (`VKCommandBuilder::record_commands`) - When completed the command buffer can be submitted to the device queue. `vkQueueSubmit` - Render graphs that have been submitted can be reused by a next thread. This is done by pushing the render graph to the `VKDevice::unused_render_graphs` queue. Pull Request: https://projects.blender.org/blender/blender/pulls/132681
2025-01-27 08:55:23 +01:00
for (const StringRef &group : debug_stack) {
std::string str_group = group;
render_graph_.value().get().debug_group_begin(str_group.c_str(),
debug::get_debug_group_color(str_group));
Vulkan: Device command builder This PR implements a new the threading model for building render graphs based on tests performed last month. For out workload multithreaded command building will block in the driver or device. So better to use a single thread for command building. Details of the internal working is documented at https://developer.blender.org/docs/features/gpu/vulkan/render_graph/ - When a context is activated on a thread the context asks for a render graph it can use by calling `VKDevice::render_graph_new`. - Parts of the GPU backend that requires GPU commands will add a specific render graph node to the render graph. The nodes also contains a reference to all resources it needs including the access it needs and the image layout. - When the context is flushed the render graph is submitted to the device by calling `VKDevice::render_graph_submit`. - The device puts the render graph in `VKDevice::submission_pool`. - There is a single background thread that gets the next render graph to send to the GPU (`VKDevice::submission_runner`). - Reorder the commands of the render graph to comply with Vulkan specific command order rules and reducing possible bottlenecks. (`VKScheduler`) - Generate the required barriers `VKCommandBuilder::groups_extract_barriers`. This is a separate step to reduce resource locking giving other threads access to the resource states when they are building the render graph nodes. - GPU commands and pipeline barriers are recorded to a VkCommandBuffer. (`VKCommandBuilder::record_commands`) - When completed the command buffer can be submitted to the device queue. `vkQueueSubmit` - Render graphs that have been submitted can be reused by a next thread. This is done by pushing the render graph to the `VKDevice::unused_render_graphs` queue. Pull Request: https://projects.blender.org/blender/blender/pulls/132681
2025-01-27 08:55:23 +01:00
}
}
is_active_ = true;
sync_backbuffer();
Vulkan: Initial Graphics Pipeline Initial graphic pipeline targeting. The goal of this PR is to have an initial graphics pipeline with missing features. It should help identifying areas that requires engineering. Current state is that developers of the GPU module can help with the many smaller pieces that needs to be engineered in order to get it working. It is not intended for users or developers from other modules, but your welcome to learn and give feedback on the code and engineering part. We do expect that large parts of the code still needs to be re-engineered into a more future-proof implementation. **Some highlights**: - In Vulkan the state is kept in the pipeline. Therefore the state is tracked per pipeline. In the near future this could be used as a cache. More research is needed against the default pipeline cache that vulkan already provides. - This PR is based on the work that Kazashi Yoshioka already did. And include work from him in the next areas - Vertex attributes - Vertex data conversions - Pipeline state - Immediate support working. - This PR modifies the VKCommandBuffer to keep track of the framebuffer and its binding state(render pass). Some Vulkan commands require no render pass to be active, other require a render pass. As the order of our commands on API level can not be separated this PR introduces a state engine to keep track of the current state and desired state. This is a temporary solution, the final solution will be proposed when we have a pixel on the screen. At that time I expect that we can design a command encoder that supports all the cases we need. **Notices**: - This branch works on NVIDIA GPUs and has been validated on a Linux system. AMD is known not to work (stalls) and Intel GPUs have not been tested at all. Windows might work but hasn't been validated yet. - The graphics pipeline is implemented with pixels in mind, not with performance. Currently when a draw call is scheduled it is flushed and waited until it is finished drawing, before other draw calls can be scheduled. We expected the performance to be worse that it actually is, but we expect huge performance gains in the future. - Any advanced drawing (that is used by the image editor, compositor or 3d viewport) isn't implemented and might crash when used. - Using multiple windows or resizing of window isn't supported and will stall the system. Pull Request: https://projects.blender.org/blender/blender/pulls/106224
2023-05-11 13:01:56 +02:00
immActivate();
}
Vulkan: Initial Graphics Pipeline Initial graphic pipeline targeting. The goal of this PR is to have an initial graphics pipeline with missing features. It should help identifying areas that requires engineering. Current state is that developers of the GPU module can help with the many smaller pieces that needs to be engineered in order to get it working. It is not intended for users or developers from other modules, but your welcome to learn and give feedback on the code and engineering part. We do expect that large parts of the code still needs to be re-engineered into a more future-proof implementation. **Some highlights**: - In Vulkan the state is kept in the pipeline. Therefore the state is tracked per pipeline. In the near future this could be used as a cache. More research is needed against the default pipeline cache that vulkan already provides. - This PR is based on the work that Kazashi Yoshioka already did. And include work from him in the next areas - Vertex attributes - Vertex data conversions - Pipeline state - Immediate support working. - This PR modifies the VKCommandBuffer to keep track of the framebuffer and its binding state(render pass). Some Vulkan commands require no render pass to be active, other require a render pass. As the order of our commands on API level can not be separated this PR introduces a state engine to keep track of the current state and desired state. This is a temporary solution, the final solution will be proposed when we have a pixel on the screen. At that time I expect that we can design a command encoder that supports all the cases we need. **Notices**: - This branch works on NVIDIA GPUs and has been validated on a Linux system. AMD is known not to work (stalls) and Intel GPUs have not been tested at all. Windows might work but hasn't been validated yet. - The graphics pipeline is implemented with pixels in mind, not with performance. Currently when a draw call is scheduled it is flushed and waited until it is finished drawing, before other draw calls can be scheduled. We expected the performance to be worse that it actually is, but we expect huge performance gains in the future. - Any advanced drawing (that is used by the image editor, compositor or 3d viewport) isn't implemented and might crash when used. - Using multiple windows or resizing of window isn't supported and will stall the system. Pull Request: https://projects.blender.org/blender/blender/pulls/106224
2023-05-11 13:01:56 +02:00
void VKContext::deactivate()
{
Vulkan: Device command builder This PR implements a new the threading model for building render graphs based on tests performed last month. For out workload multithreaded command building will block in the driver or device. So better to use a single thread for command building. Details of the internal working is documented at https://developer.blender.org/docs/features/gpu/vulkan/render_graph/ - When a context is activated on a thread the context asks for a render graph it can use by calling `VKDevice::render_graph_new`. - Parts of the GPU backend that requires GPU commands will add a specific render graph node to the render graph. The nodes also contains a reference to all resources it needs including the access it needs and the image layout. - When the context is flushed the render graph is submitted to the device by calling `VKDevice::render_graph_submit`. - The device puts the render graph in `VKDevice::submission_pool`. - There is a single background thread that gets the next render graph to send to the GPU (`VKDevice::submission_runner`). - Reorder the commands of the render graph to comply with Vulkan specific command order rules and reducing possible bottlenecks. (`VKScheduler`) - Generate the required barriers `VKCommandBuilder::groups_extract_barriers`. This is a separate step to reduce resource locking giving other threads access to the resource states when they are building the render graph nodes. - GPU commands and pipeline barriers are recorded to a VkCommandBuffer. (`VKCommandBuilder::record_commands`) - When completed the command buffer can be submitted to the device queue. `vkQueueSubmit` - Render graphs that have been submitted can be reused by a next thread. This is done by pushing the render graph to the `VKDevice::unused_render_graphs` queue. Pull Request: https://projects.blender.org/blender/blender/pulls/132681
2025-01-27 08:55:23 +01:00
flush_render_graph(RenderGraphFlushFlags(0));
Vulkan: Initial Graphics Pipeline Initial graphic pipeline targeting. The goal of this PR is to have an initial graphics pipeline with missing features. It should help identifying areas that requires engineering. Current state is that developers of the GPU module can help with the many smaller pieces that needs to be engineered in order to get it working. It is not intended for users or developers from other modules, but your welcome to learn and give feedback on the code and engineering part. We do expect that large parts of the code still needs to be re-engineered into a more future-proof implementation. **Some highlights**: - In Vulkan the state is kept in the pipeline. Therefore the state is tracked per pipeline. In the near future this could be used as a cache. More research is needed against the default pipeline cache that vulkan already provides. - This PR is based on the work that Kazashi Yoshioka already did. And include work from him in the next areas - Vertex attributes - Vertex data conversions - Pipeline state - Immediate support working. - This PR modifies the VKCommandBuffer to keep track of the framebuffer and its binding state(render pass). Some Vulkan commands require no render pass to be active, other require a render pass. As the order of our commands on API level can not be separated this PR introduces a state engine to keep track of the current state and desired state. This is a temporary solution, the final solution will be proposed when we have a pixel on the screen. At that time I expect that we can design a command encoder that supports all the cases we need. **Notices**: - This branch works on NVIDIA GPUs and has been validated on a Linux system. AMD is known not to work (stalls) and Intel GPUs have not been tested at all. Windows might work but hasn't been validated yet. - The graphics pipeline is implemented with pixels in mind, not with performance. Currently when a draw call is scheduled it is flushed and waited until it is finished drawing, before other draw calls can be scheduled. We expected the performance to be worse that it actually is, but we expect huge performance gains in the future. - Any advanced drawing (that is used by the image editor, compositor or 3d viewport) isn't implemented and might crash when used. - Using multiple windows or resizing of window isn't supported and will stall the system. Pull Request: https://projects.blender.org/blender/blender/pulls/106224
2023-05-11 13:01:56 +02:00
immDeactivate();
thread_data_.reset();
Vulkan: Device command builder This PR implements a new the threading model for building render graphs based on tests performed last month. For out workload multithreaded command building will block in the driver or device. So better to use a single thread for command building. Details of the internal working is documented at https://developer.blender.org/docs/features/gpu/vulkan/render_graph/ - When a context is activated on a thread the context asks for a render graph it can use by calling `VKDevice::render_graph_new`. - Parts of the GPU backend that requires GPU commands will add a specific render graph node to the render graph. The nodes also contains a reference to all resources it needs including the access it needs and the image layout. - When the context is flushed the render graph is submitted to the device by calling `VKDevice::render_graph_submit`. - The device puts the render graph in `VKDevice::submission_pool`. - There is a single background thread that gets the next render graph to send to the GPU (`VKDevice::submission_runner`). - Reorder the commands of the render graph to comply with Vulkan specific command order rules and reducing possible bottlenecks. (`VKScheduler`) - Generate the required barriers `VKCommandBuilder::groups_extract_barriers`. This is a separate step to reduce resource locking giving other threads access to the resource states when they are building the render graph nodes. - GPU commands and pipeline barriers are recorded to a VkCommandBuffer. (`VKCommandBuilder::record_commands`) - When completed the command buffer can be submitted to the device queue. `vkQueueSubmit` - Render graphs that have been submitted can be reused by a next thread. This is done by pushing the render graph to the `VKDevice::unused_render_graphs` queue. Pull Request: https://projects.blender.org/blender/blender/pulls/132681
2025-01-27 08:55:23 +01:00
Vulkan: Initial Graphics Pipeline Initial graphic pipeline targeting. The goal of this PR is to have an initial graphics pipeline with missing features. It should help identifying areas that requires engineering. Current state is that developers of the GPU module can help with the many smaller pieces that needs to be engineered in order to get it working. It is not intended for users or developers from other modules, but your welcome to learn and give feedback on the code and engineering part. We do expect that large parts of the code still needs to be re-engineered into a more future-proof implementation. **Some highlights**: - In Vulkan the state is kept in the pipeline. Therefore the state is tracked per pipeline. In the near future this could be used as a cache. More research is needed against the default pipeline cache that vulkan already provides. - This PR is based on the work that Kazashi Yoshioka already did. And include work from him in the next areas - Vertex attributes - Vertex data conversions - Pipeline state - Immediate support working. - This PR modifies the VKCommandBuffer to keep track of the framebuffer and its binding state(render pass). Some Vulkan commands require no render pass to be active, other require a render pass. As the order of our commands on API level can not be separated this PR introduces a state engine to keep track of the current state and desired state. This is a temporary solution, the final solution will be proposed when we have a pixel on the screen. At that time I expect that we can design a command encoder that supports all the cases we need. **Notices**: - This branch works on NVIDIA GPUs and has been validated on a Linux system. AMD is known not to work (stalls) and Intel GPUs have not been tested at all. Windows might work but hasn't been validated yet. - The graphics pipeline is implemented with pixels in mind, not with performance. Currently when a draw call is scheduled it is flushed and waited until it is finished drawing, before other draw calls can be scheduled. We expected the performance to be worse that it actually is, but we expect huge performance gains in the future. - Any advanced drawing (that is used by the image editor, compositor or 3d viewport) isn't implemented and might crash when used. - Using multiple windows or resizing of window isn't supported and will stall the system. Pull Request: https://projects.blender.org/blender/blender/pulls/106224
2023-05-11 13:01:56 +02:00
is_active_ = false;
}
Vulkan: Rewrite GHOST_ContextVK This is a rewrite of GHOST_ContextVK to align with Metal backend as described in #111389 - solution 3 with the adaptation that GHOST is still responsible for presenting the swap chain image and a post callback is still needed in case the swapchain is recreated. This PR also includes some smaller improvements in stability. Technical documentation: https://developer.blender.org/docs/eevee_and_viewport/gpu/vulkan/swap_chain/ * Renderpasses and framebuffers are not owned anymore by GHOST_ContextVK * VKFramebuffer doesn't contain a swap chain image. * Swapchain images can only be used as a blit destination or present source. Not as an attachment. * GHOST_ContextVK::swapBuffers would call a callback with the image the GPU module needs to blit the results to. * Clearing of depth/stencil attachments when no depth write state is set. * Enable VK_KHR_maintenance4 to relax the stage interface mapping. * Removes most vulkan validation warnings/errors. * Detection of frame buffer changes that needs to be applied before performing a command requiring render pass (draw/clear attachment) **Benefits** * Late retrieval of a swap chain image results in better overall performance as Blender doesn't need to wait until the image is presented on the screen. * Easier API and clearer state (transitions) * More control over Image layouts and command buffer states. (Better alignment with Vulkan API) Pull Request: https://projects.blender.org/blender/blender/pulls/111473
2023-08-29 15:05:08 +02:00
void VKContext::begin_frame() {}
Vulkan: Device command builder This PR implements a new the threading model for building render graphs based on tests performed last month. For out workload multithreaded command building will block in the driver or device. So better to use a single thread for command building. Details of the internal working is documented at https://developer.blender.org/docs/features/gpu/vulkan/render_graph/ - When a context is activated on a thread the context asks for a render graph it can use by calling `VKDevice::render_graph_new`. - Parts of the GPU backend that requires GPU commands will add a specific render graph node to the render graph. The nodes also contains a reference to all resources it needs including the access it needs and the image layout. - When the context is flushed the render graph is submitted to the device by calling `VKDevice::render_graph_submit`. - The device puts the render graph in `VKDevice::submission_pool`. - There is a single background thread that gets the next render graph to send to the GPU (`VKDevice::submission_runner`). - Reorder the commands of the render graph to comply with Vulkan specific command order rules and reducing possible bottlenecks. (`VKScheduler`) - Generate the required barriers `VKCommandBuilder::groups_extract_barriers`. This is a separate step to reduce resource locking giving other threads access to the resource states when they are building the render graph nodes. - GPU commands and pipeline barriers are recorded to a VkCommandBuffer. (`VKCommandBuilder::record_commands`) - When completed the command buffer can be submitted to the device queue. `vkQueueSubmit` - Render graphs that have been submitted can be reused by a next thread. This is done by pushing the render graph to the `VKDevice::unused_render_graphs` queue. Pull Request: https://projects.blender.org/blender/blender/pulls/132681
2025-01-27 08:55:23 +01:00
void VKContext::end_frame()
{
this->process_frame_timings();
Vulkan: Device command builder This PR implements a new the threading model for building render graphs based on tests performed last month. For out workload multithreaded command building will block in the driver or device. So better to use a single thread for command building. Details of the internal working is documented at https://developer.blender.org/docs/features/gpu/vulkan/render_graph/ - When a context is activated on a thread the context asks for a render graph it can use by calling `VKDevice::render_graph_new`. - Parts of the GPU backend that requires GPU commands will add a specific render graph node to the render graph. The nodes also contains a reference to all resources it needs including the access it needs and the image layout. - When the context is flushed the render graph is submitted to the device by calling `VKDevice::render_graph_submit`. - The device puts the render graph in `VKDevice::submission_pool`. - There is a single background thread that gets the next render graph to send to the GPU (`VKDevice::submission_runner`). - Reorder the commands of the render graph to comply with Vulkan specific command order rules and reducing possible bottlenecks. (`VKScheduler`) - Generate the required barriers `VKCommandBuilder::groups_extract_barriers`. This is a separate step to reduce resource locking giving other threads access to the resource states when they are building the render graph nodes. - GPU commands and pipeline barriers are recorded to a VkCommandBuffer. (`VKCommandBuilder::record_commands`) - When completed the command buffer can be submitted to the device queue. `vkQueueSubmit` - Render graphs that have been submitted can be reused by a next thread. This is done by pushing the render graph to the `VKDevice::unused_render_graphs` queue. Pull Request: https://projects.blender.org/blender/blender/pulls/132681
2025-01-27 08:55:23 +01:00
}
void VKContext::flush()
{
flush_render_graph(RenderGraphFlushFlags::RENEW_RENDER_GRAPH);
}
TimelineValue VKContext::flush_render_graph(RenderGraphFlushFlags flags,
VkPipelineStageFlags wait_dst_stage_mask,
VkSemaphore wait_semaphore,
VkSemaphore signal_semaphore,
VkFence signal_fence)
{
if (has_active_framebuffer()) {
VKFrameBuffer &framebuffer = *active_framebuffer_get();
if (framebuffer.is_rendering()) {
framebuffer.rendering_end(*this);
}
}
Vulkan: Device command builder This PR implements a new the threading model for building render graphs based on tests performed last month. For out workload multithreaded command building will block in the driver or device. So better to use a single thread for command building. Details of the internal working is documented at https://developer.blender.org/docs/features/gpu/vulkan/render_graph/ - When a context is activated on a thread the context asks for a render graph it can use by calling `VKDevice::render_graph_new`. - Parts of the GPU backend that requires GPU commands will add a specific render graph node to the render graph. The nodes also contains a reference to all resources it needs including the access it needs and the image layout. - When the context is flushed the render graph is submitted to the device by calling `VKDevice::render_graph_submit`. - The device puts the render graph in `VKDevice::submission_pool`. - There is a single background thread that gets the next render graph to send to the GPU (`VKDevice::submission_runner`). - Reorder the commands of the render graph to comply with Vulkan specific command order rules and reducing possible bottlenecks. (`VKScheduler`) - Generate the required barriers `VKCommandBuilder::groups_extract_barriers`. This is a separate step to reduce resource locking giving other threads access to the resource states when they are building the render graph nodes. - GPU commands and pipeline barriers are recorded to a VkCommandBuffer. (`VKCommandBuilder::record_commands`) - When completed the command buffer can be submitted to the device queue. `vkQueueSubmit` - Render graphs that have been submitted can be reused by a next thread. This is done by pushing the render graph to the `VKDevice::unused_render_graphs` queue. Pull Request: https://projects.blender.org/blender/blender/pulls/132681
2025-01-27 08:55:23 +01:00
VKDevice &device = VKBackend::get().device;
descriptor_set_get().upload_descriptor_sets();
Vulkan: Device command builder This PR implements a new the threading model for building render graphs based on tests performed last month. For out workload multithreaded command building will block in the driver or device. So better to use a single thread for command building. Details of the internal working is documented at https://developer.blender.org/docs/features/gpu/vulkan/render_graph/ - When a context is activated on a thread the context asks for a render graph it can use by calling `VKDevice::render_graph_new`. - Parts of the GPU backend that requires GPU commands will add a specific render graph node to the render graph. The nodes also contains a reference to all resources it needs including the access it needs and the image layout. - When the context is flushed the render graph is submitted to the device by calling `VKDevice::render_graph_submit`. - The device puts the render graph in `VKDevice::submission_pool`. - There is a single background thread that gets the next render graph to send to the GPU (`VKDevice::submission_runner`). - Reorder the commands of the render graph to comply with Vulkan specific command order rules and reducing possible bottlenecks. (`VKScheduler`) - Generate the required barriers `VKCommandBuilder::groups_extract_barriers`. This is a separate step to reduce resource locking giving other threads access to the resource states when they are building the render graph nodes. - GPU commands and pipeline barriers are recorded to a VkCommandBuffer. (`VKCommandBuilder::record_commands`) - When completed the command buffer can be submitted to the device queue. `vkQueueSubmit` - Render graphs that have been submitted can be reused by a next thread. This is done by pushing the render graph to the `VKDevice::unused_render_graphs` queue. Pull Request: https://projects.blender.org/blender/blender/pulls/132681
2025-01-27 08:55:23 +01:00
TimelineValue timeline = device.render_graph_submit(
&render_graph_.value().get(),
discard_pool,
bool(flags & RenderGraphFlushFlags::SUBMIT),
bool(flags & RenderGraphFlushFlags::WAIT_FOR_COMPLETION),
wait_dst_stage_mask,
wait_semaphore,
signal_semaphore,
signal_fence);
Vulkan: Device command builder This PR implements a new the threading model for building render graphs based on tests performed last month. For out workload multithreaded command building will block in the driver or device. So better to use a single thread for command building. Details of the internal working is documented at https://developer.blender.org/docs/features/gpu/vulkan/render_graph/ - When a context is activated on a thread the context asks for a render graph it can use by calling `VKDevice::render_graph_new`. - Parts of the GPU backend that requires GPU commands will add a specific render graph node to the render graph. The nodes also contains a reference to all resources it needs including the access it needs and the image layout. - When the context is flushed the render graph is submitted to the device by calling `VKDevice::render_graph_submit`. - The device puts the render graph in `VKDevice::submission_pool`. - There is a single background thread that gets the next render graph to send to the GPU (`VKDevice::submission_runner`). - Reorder the commands of the render graph to comply with Vulkan specific command order rules and reducing possible bottlenecks. (`VKScheduler`) - Generate the required barriers `VKCommandBuilder::groups_extract_barriers`. This is a separate step to reduce resource locking giving other threads access to the resource states when they are building the render graph nodes. - GPU commands and pipeline barriers are recorded to a VkCommandBuffer. (`VKCommandBuilder::record_commands`) - When completed the command buffer can be submitted to the device queue. `vkQueueSubmit` - Render graphs that have been submitted can be reused by a next thread. This is done by pushing the render graph to the `VKDevice::unused_render_graphs` queue. Pull Request: https://projects.blender.org/blender/blender/pulls/132681
2025-01-27 08:55:23 +01:00
render_graph_.reset();
if (bool(flags & RenderGraphFlushFlags::RENEW_RENDER_GRAPH)) {
render_graph_ = std::reference_wrapper<render_graph::VKRenderGraph>(
*device.render_graph_new());
/* Recreate the debug group stack for the new graph.
* Note: there is no associated `debug_group_end` as the graph groups
* are implicitly closed on submission. */
Vulkan: Device command builder This PR implements a new the threading model for building render graphs based on tests performed last month. For out workload multithreaded command building will block in the driver or device. So better to use a single thread for command building. Details of the internal working is documented at https://developer.blender.org/docs/features/gpu/vulkan/render_graph/ - When a context is activated on a thread the context asks for a render graph it can use by calling `VKDevice::render_graph_new`. - Parts of the GPU backend that requires GPU commands will add a specific render graph node to the render graph. The nodes also contains a reference to all resources it needs including the access it needs and the image layout. - When the context is flushed the render graph is submitted to the device by calling `VKDevice::render_graph_submit`. - The device puts the render graph in `VKDevice::submission_pool`. - There is a single background thread that gets the next render graph to send to the GPU (`VKDevice::submission_runner`). - Reorder the commands of the render graph to comply with Vulkan specific command order rules and reducing possible bottlenecks. (`VKScheduler`) - Generate the required barriers `VKCommandBuilder::groups_extract_barriers`. This is a separate step to reduce resource locking giving other threads access to the resource states when they are building the render graph nodes. - GPU commands and pipeline barriers are recorded to a VkCommandBuffer. (`VKCommandBuilder::record_commands`) - When completed the command buffer can be submitted to the device queue. `vkQueueSubmit` - Render graphs that have been submitted can be reused by a next thread. This is done by pushing the render graph to the `VKDevice::unused_render_graphs` queue. Pull Request: https://projects.blender.org/blender/blender/pulls/132681
2025-01-27 08:55:23 +01:00
for (const StringRef &group : debug_stack) {
std::string str_group = group;
render_graph_.value().get().debug_group_begin(str_group.c_str(),
debug::get_debug_group_color(str_group));
Vulkan: Device command builder This PR implements a new the threading model for building render graphs based on tests performed last month. For out workload multithreaded command building will block in the driver or device. So better to use a single thread for command building. Details of the internal working is documented at https://developer.blender.org/docs/features/gpu/vulkan/render_graph/ - When a context is activated on a thread the context asks for a render graph it can use by calling `VKDevice::render_graph_new`. - Parts of the GPU backend that requires GPU commands will add a specific render graph node to the render graph. The nodes also contains a reference to all resources it needs including the access it needs and the image layout. - When the context is flushed the render graph is submitted to the device by calling `VKDevice::render_graph_submit`. - The device puts the render graph in `VKDevice::submission_pool`. - There is a single background thread that gets the next render graph to send to the GPU (`VKDevice::submission_runner`). - Reorder the commands of the render graph to comply with Vulkan specific command order rules and reducing possible bottlenecks. (`VKScheduler`) - Generate the required barriers `VKCommandBuilder::groups_extract_barriers`. This is a separate step to reduce resource locking giving other threads access to the resource states when they are building the render graph nodes. - GPU commands and pipeline barriers are recorded to a VkCommandBuffer. (`VKCommandBuilder::record_commands`) - When completed the command buffer can be submitted to the device queue. `vkQueueSubmit` - Render graphs that have been submitted can be reused by a next thread. This is done by pushing the render graph to the `VKDevice::unused_render_graphs` queue. Pull Request: https://projects.blender.org/blender/blender/pulls/132681
2025-01-27 08:55:23 +01:00
}
}
return timeline;
}
void VKContext::finish() {}
void VKContext::memory_statistics_get(int *r_total_mem_kb, int *r_free_mem_kb)
{
const VKDevice &device = VKBackend::get().device;
device.memory_statistics_get(r_total_mem_kb, r_free_mem_kb);
}
/* -------------------------------------------------------------------- */
/** \name State manager
* \{ */
VKDescriptorPools &VKContext::descriptor_pools_get()
{
return thread_data_.value().get().descriptor_pools;
}
VKDescriptorSetTracker &VKContext::descriptor_set_get()
{
return thread_data_.value().get().descriptor_set;
}
VKStateManager &VKContext::state_manager_get() const
Vulkan: Initial Graphics Pipeline Initial graphic pipeline targeting. The goal of this PR is to have an initial graphics pipeline with missing features. It should help identifying areas that requires engineering. Current state is that developers of the GPU module can help with the many smaller pieces that needs to be engineered in order to get it working. It is not intended for users or developers from other modules, but your welcome to learn and give feedback on the code and engineering part. We do expect that large parts of the code still needs to be re-engineered into a more future-proof implementation. **Some highlights**: - In Vulkan the state is kept in the pipeline. Therefore the state is tracked per pipeline. In the near future this could be used as a cache. More research is needed against the default pipeline cache that vulkan already provides. - This PR is based on the work that Kazashi Yoshioka already did. And include work from him in the next areas - Vertex attributes - Vertex data conversions - Pipeline state - Immediate support working. - This PR modifies the VKCommandBuffer to keep track of the framebuffer and its binding state(render pass). Some Vulkan commands require no render pass to be active, other require a render pass. As the order of our commands on API level can not be separated this PR introduces a state engine to keep track of the current state and desired state. This is a temporary solution, the final solution will be proposed when we have a pixel on the screen. At that time I expect that we can design a command encoder that supports all the cases we need. **Notices**: - This branch works on NVIDIA GPUs and has been validated on a Linux system. AMD is known not to work (stalls) and Intel GPUs have not been tested at all. Windows might work but hasn't been validated yet. - The graphics pipeline is implemented with pixels in mind, not with performance. Currently when a draw call is scheduled it is flushed and waited until it is finished drawing, before other draw calls can be scheduled. We expected the performance to be worse that it actually is, but we expect huge performance gains in the future. - Any advanced drawing (that is used by the image editor, compositor or 3d viewport) isn't implemented and might crash when used. - Using multiple windows or resizing of window isn't supported and will stall the system. Pull Request: https://projects.blender.org/blender/blender/pulls/106224
2023-05-11 13:01:56 +02:00
{
return *static_cast<VKStateManager *>(state_manager);
}
void VKContext::debug_unbind_all_ubo()
{
state_manager_get().uniform_buffer_unbind_all();
};
void VKContext::debug_unbind_all_ssbo()
{
state_manager_get().storage_buffer_unbind_all();
};
/** \} */
Vulkan: Initial Graphics Pipeline Initial graphic pipeline targeting. The goal of this PR is to have an initial graphics pipeline with missing features. It should help identifying areas that requires engineering. Current state is that developers of the GPU module can help with the many smaller pieces that needs to be engineered in order to get it working. It is not intended for users or developers from other modules, but your welcome to learn and give feedback on the code and engineering part. We do expect that large parts of the code still needs to be re-engineered into a more future-proof implementation. **Some highlights**: - In Vulkan the state is kept in the pipeline. Therefore the state is tracked per pipeline. In the near future this could be used as a cache. More research is needed against the default pipeline cache that vulkan already provides. - This PR is based on the work that Kazashi Yoshioka already did. And include work from him in the next areas - Vertex attributes - Vertex data conversions - Pipeline state - Immediate support working. - This PR modifies the VKCommandBuffer to keep track of the framebuffer and its binding state(render pass). Some Vulkan commands require no render pass to be active, other require a render pass. As the order of our commands on API level can not be separated this PR introduces a state engine to keep track of the current state and desired state. This is a temporary solution, the final solution will be proposed when we have a pixel on the screen. At that time I expect that we can design a command encoder that supports all the cases we need. **Notices**: - This branch works on NVIDIA GPUs and has been validated on a Linux system. AMD is known not to work (stalls) and Intel GPUs have not been tested at all. Windows might work but hasn't been validated yet. - The graphics pipeline is implemented with pixels in mind, not with performance. Currently when a draw call is scheduled it is flushed and waited until it is finished drawing, before other draw calls can be scheduled. We expected the performance to be worse that it actually is, but we expect huge performance gains in the future. - Any advanced drawing (that is used by the image editor, compositor or 3d viewport) isn't implemented and might crash when used. - Using multiple windows or resizing of window isn't supported and will stall the system. Pull Request: https://projects.blender.org/blender/blender/pulls/106224
2023-05-11 13:01:56 +02:00
/* -------------------------------------------------------------------- */
/** \name Frame-buffer
Vulkan: Initial Graphics Pipeline Initial graphic pipeline targeting. The goal of this PR is to have an initial graphics pipeline with missing features. It should help identifying areas that requires engineering. Current state is that developers of the GPU module can help with the many smaller pieces that needs to be engineered in order to get it working. It is not intended for users or developers from other modules, but your welcome to learn and give feedback on the code and engineering part. We do expect that large parts of the code still needs to be re-engineered into a more future-proof implementation. **Some highlights**: - In Vulkan the state is kept in the pipeline. Therefore the state is tracked per pipeline. In the near future this could be used as a cache. More research is needed against the default pipeline cache that vulkan already provides. - This PR is based on the work that Kazashi Yoshioka already did. And include work from him in the next areas - Vertex attributes - Vertex data conversions - Pipeline state - Immediate support working. - This PR modifies the VKCommandBuffer to keep track of the framebuffer and its binding state(render pass). Some Vulkan commands require no render pass to be active, other require a render pass. As the order of our commands on API level can not be separated this PR introduces a state engine to keep track of the current state and desired state. This is a temporary solution, the final solution will be proposed when we have a pixel on the screen. At that time I expect that we can design a command encoder that supports all the cases we need. **Notices**: - This branch works on NVIDIA GPUs and has been validated on a Linux system. AMD is known not to work (stalls) and Intel GPUs have not been tested at all. Windows might work but hasn't been validated yet. - The graphics pipeline is implemented with pixels in mind, not with performance. Currently when a draw call is scheduled it is flushed and waited until it is finished drawing, before other draw calls can be scheduled. We expected the performance to be worse that it actually is, but we expect huge performance gains in the future. - Any advanced drawing (that is used by the image editor, compositor or 3d viewport) isn't implemented and might crash when used. - Using multiple windows or resizing of window isn't supported and will stall the system. Pull Request: https://projects.blender.org/blender/blender/pulls/106224
2023-05-11 13:01:56 +02:00
* \{ */
void VKContext::activate_framebuffer(VKFrameBuffer &framebuffer)
{
if (has_active_framebuffer()) {
deactivate_framebuffer();
}
BLI_assert(active_fb == nullptr);
active_fb = &framebuffer;
Vulkan: Rewrite GHOST_ContextVK This is a rewrite of GHOST_ContextVK to align with Metal backend as described in #111389 - solution 3 with the adaptation that GHOST is still responsible for presenting the swap chain image and a post callback is still needed in case the swapchain is recreated. This PR also includes some smaller improvements in stability. Technical documentation: https://developer.blender.org/docs/eevee_and_viewport/gpu/vulkan/swap_chain/ * Renderpasses and framebuffers are not owned anymore by GHOST_ContextVK * VKFramebuffer doesn't contain a swap chain image. * Swapchain images can only be used as a blit destination or present source. Not as an attachment. * GHOST_ContextVK::swapBuffers would call a callback with the image the GPU module needs to blit the results to. * Clearing of depth/stencil attachments when no depth write state is set. * Enable VK_KHR_maintenance4 to relax the stage interface mapping. * Removes most vulkan validation warnings/errors. * Detection of frame buffer changes that needs to be applied before performing a command requiring render pass (draw/clear attachment) **Benefits** * Late retrieval of a swap chain image results in better overall performance as Blender doesn't need to wait until the image is presented on the screen. * Easier API and clearer state (transitions) * More control over Image layouts and command buffer states. (Better alignment with Vulkan API) Pull Request: https://projects.blender.org/blender/blender/pulls/111473
2023-08-29 15:05:08 +02:00
framebuffer.update_size();
framebuffer.update_srgb();
framebuffer.rendering_reset();
}
VKFrameBuffer *VKContext::active_framebuffer_get() const
{
return unwrap(active_fb);
}
bool VKContext::has_active_framebuffer() const
{
return active_framebuffer_get() != nullptr;
}
void VKContext::deactivate_framebuffer()
{
VKFrameBuffer *framebuffer = active_framebuffer_get();
Vulkan: Initial Graphics Pipeline Initial graphic pipeline targeting. The goal of this PR is to have an initial graphics pipeline with missing features. It should help identifying areas that requires engineering. Current state is that developers of the GPU module can help with the many smaller pieces that needs to be engineered in order to get it working. It is not intended for users or developers from other modules, but your welcome to learn and give feedback on the code and engineering part. We do expect that large parts of the code still needs to be re-engineered into a more future-proof implementation. **Some highlights**: - In Vulkan the state is kept in the pipeline. Therefore the state is tracked per pipeline. In the near future this could be used as a cache. More research is needed against the default pipeline cache that vulkan already provides. - This PR is based on the work that Kazashi Yoshioka already did. And include work from him in the next areas - Vertex attributes - Vertex data conversions - Pipeline state - Immediate support working. - This PR modifies the VKCommandBuffer to keep track of the framebuffer and its binding state(render pass). Some Vulkan commands require no render pass to be active, other require a render pass. As the order of our commands on API level can not be separated this PR introduces a state engine to keep track of the current state and desired state. This is a temporary solution, the final solution will be proposed when we have a pixel on the screen. At that time I expect that we can design a command encoder that supports all the cases we need. **Notices**: - This branch works on NVIDIA GPUs and has been validated on a Linux system. AMD is known not to work (stalls) and Intel GPUs have not been tested at all. Windows might work but hasn't been validated yet. - The graphics pipeline is implemented with pixels in mind, not with performance. Currently when a draw call is scheduled it is flushed and waited until it is finished drawing, before other draw calls can be scheduled. We expected the performance to be worse that it actually is, but we expect huge performance gains in the future. - Any advanced drawing (that is used by the image editor, compositor or 3d viewport) isn't implemented and might crash when used. - Using multiple windows or resizing of window isn't supported and will stall the system. Pull Request: https://projects.blender.org/blender/blender/pulls/106224
2023-05-11 13:01:56 +02:00
BLI_assert(framebuffer != nullptr);
if (framebuffer->is_rendering()) {
framebuffer->rendering_end(*this);
}
active_fb = nullptr;
}
void VKContext::rendering_end()
{
VKFrameBuffer *framebuffer = active_framebuffer_get();
if (framebuffer) {
framebuffer->rendering_end(*this);
}
}
Vulkan: Initial Graphics Pipeline Initial graphic pipeline targeting. The goal of this PR is to have an initial graphics pipeline with missing features. It should help identifying areas that requires engineering. Current state is that developers of the GPU module can help with the many smaller pieces that needs to be engineered in order to get it working. It is not intended for users or developers from other modules, but your welcome to learn and give feedback on the code and engineering part. We do expect that large parts of the code still needs to be re-engineered into a more future-proof implementation. **Some highlights**: - In Vulkan the state is kept in the pipeline. Therefore the state is tracked per pipeline. In the near future this could be used as a cache. More research is needed against the default pipeline cache that vulkan already provides. - This PR is based on the work that Kazashi Yoshioka already did. And include work from him in the next areas - Vertex attributes - Vertex data conversions - Pipeline state - Immediate support working. - This PR modifies the VKCommandBuffer to keep track of the framebuffer and its binding state(render pass). Some Vulkan commands require no render pass to be active, other require a render pass. As the order of our commands on API level can not be separated this PR introduces a state engine to keep track of the current state and desired state. This is a temporary solution, the final solution will be proposed when we have a pixel on the screen. At that time I expect that we can design a command encoder that supports all the cases we need. **Notices**: - This branch works on NVIDIA GPUs and has been validated on a Linux system. AMD is known not to work (stalls) and Intel GPUs have not been tested at all. Windows might work but hasn't been validated yet. - The graphics pipeline is implemented with pixels in mind, not with performance. Currently when a draw call is scheduled it is flushed and waited until it is finished drawing, before other draw calls can be scheduled. We expected the performance to be worse that it actually is, but we expect huge performance gains in the future. - Any advanced drawing (that is used by the image editor, compositor or 3d viewport) isn't implemented and might crash when used. - Using multiple windows or resizing of window isn't supported and will stall the system. Pull Request: https://projects.blender.org/blender/blender/pulls/106224
2023-05-11 13:01:56 +02:00
/** \} */
/* -------------------------------------------------------------------- */
/** \name Pipeline
* \{ */
void VKContext::update_pipeline_data(GPUPrimType primitive,
VKVertexAttributeObject &vao,
render_graph::VKPipelineData &r_pipeline_data)
{
VKShader &vk_shader = unwrap(*shader);
VKFrameBuffer &framebuffer = *active_framebuffer_get();
/* Override size of point shader when GPU_point size < 0 */
const float point_size = state_manager_get().mutable_state.point_size;
if (primitive == GPU_PRIM_POINTS && point_size < 0.0) {
GPU_shader_uniform_1f(shader, "size", -point_size);
}
update_pipeline_data(vk_shader,
vk_shader.ensure_and_get_graphics_pipeline(
primitive, vao, state_manager_get(), framebuffer, constants_state_),
r_pipeline_data);
}
void VKContext::update_pipeline_data(render_graph::VKPipelineData &r_pipeline_data)
{
VKShader &vk_shader = unwrap(*shader);
update_pipeline_data(
vk_shader, vk_shader.ensure_and_get_compute_pipeline(constants_state_), r_pipeline_data);
}
void VKContext::update_pipeline_data(VKShader &vk_shader,
VkPipeline vk_pipeline,
render_graph::VKPipelineData &r_pipeline_data)
{
r_pipeline_data.vk_pipeline_layout = vk_shader.vk_pipeline_layout;
r_pipeline_data.vk_pipeline = vk_pipeline;
/* Update push constants. */
r_pipeline_data.push_constants_data = nullptr;
r_pipeline_data.push_constants_size = 0;
const VKPushConstants::Layout &push_constants_layout =
vk_shader.interface_get().push_constants_layout_get();
if (push_constants_layout.storage_type_get() == VKPushConstants::StorageType::PUSH_CONSTANTS) {
r_pipeline_data.push_constants_size = push_constants_layout.size_in_bytes();
r_pipeline_data.push_constants_data = vk_shader.push_constants.data();
}
/* Update descriptor set. */
r_pipeline_data.vk_descriptor_set = VK_NULL_HANDLE;
r_pipeline_data.descriptor_buffer_device_address = 0;
r_pipeline_data.descriptor_buffer_offset = 0;
if (vk_shader.has_descriptor_set()) {
VKDescriptorSetTracker &descriptor_set = descriptor_set_get();
descriptor_set.update_descriptor_set(*this, access_info_, r_pipeline_data);
}
}
Vulkan: Refactor resource binding Resource binding was over-complicated as I didn't understood the state manager and vulkan to make the correct decisions at that time. This refactor will remove a lot of the complexity and improves the performance. **Performance** The performance improvement is noticeable in complex grease pencil scenes. Grease pencil benchmark file picknick: - `NVIDIA Quadro RTX 6000` 17 fps -> 24 fps - `Intel(R) Arc(tm) A750 Graphics (DG2)` 6 -> 21 fps **Bottle-neck** The performance improvements originates from moving the update entry point from state manager to shader interface. The previous implementation (state manager) had to loop over all the bound resources and find in the shader interface where it was located in the descriptor set. Ignoring resources that were not used by the shader. But also making it hard to determine if descriptor sets actually changed. Previous implementation assumed descriptor sets always changed. When descriptor set changed a new descriptor set needed to be allocated. Most drivers this is a fast operation, but on Intel/Mesa this was measurable slow. Using an allocation pool doesn't fit the Vulkan API as you are only able to reuse when the layout matches exactly. Of course doable, but requires another structure to keep track of the actual layouts. **Solution** By using the shader interface as entry point we can: 1. Keep track if there are any changes in the state manager. If not and the layout is the same, the previous shader can be reused. 2. In stead of looping over each bound resource, we loop over bind points. **Future extensions** Bundle all descriptor set uploads just before use. This would be more in line with how 'modern' Vulkan should be implemented. This PR already separates the uploading from the updating and technically allows to upload more than one descriptor set. Instead of looking 1 set back we should measure if we can handle multiple or keep track of the different layouts resources to improve the performance even further. Optional use `VK_KHR_descriptor_buffer` when available. Pull Request: https://projects.blender.org/blender/blender/pulls/128068
2024-09-26 10:59:45 +02:00
render_graph::VKResourceAccessInfo &VKContext::reset_and_get_access_info()
{
access_info_.reset();
return access_info_;
}
Vulkan: Initial Graphics Pipeline Initial graphic pipeline targeting. The goal of this PR is to have an initial graphics pipeline with missing features. It should help identifying areas that requires engineering. Current state is that developers of the GPU module can help with the many smaller pieces that needs to be engineered in order to get it working. It is not intended for users or developers from other modules, but your welcome to learn and give feedback on the code and engineering part. We do expect that large parts of the code still needs to be re-engineered into a more future-proof implementation. **Some highlights**: - In Vulkan the state is kept in the pipeline. Therefore the state is tracked per pipeline. In the near future this could be used as a cache. More research is needed against the default pipeline cache that vulkan already provides. - This PR is based on the work that Kazashi Yoshioka already did. And include work from him in the next areas - Vertex attributes - Vertex data conversions - Pipeline state - Immediate support working. - This PR modifies the VKCommandBuffer to keep track of the framebuffer and its binding state(render pass). Some Vulkan commands require no render pass to be active, other require a render pass. As the order of our commands on API level can not be separated this PR introduces a state engine to keep track of the current state and desired state. This is a temporary solution, the final solution will be proposed when we have a pixel on the screen. At that time I expect that we can design a command encoder that supports all the cases we need. **Notices**: - This branch works on NVIDIA GPUs and has been validated on a Linux system. AMD is known not to work (stalls) and Intel GPUs have not been tested at all. Windows might work but hasn't been validated yet. - The graphics pipeline is implemented with pixels in mind, not with performance. Currently when a draw call is scheduled it is flushed and waited until it is finished drawing, before other draw calls can be scheduled. We expected the performance to be worse that it actually is, but we expect huge performance gains in the future. - Any advanced drawing (that is used by the image editor, compositor or 3d viewport) isn't implemented and might crash when used. - Using multiple windows or resizing of window isn't supported and will stall the system. Pull Request: https://projects.blender.org/blender/blender/pulls/106224
2023-05-11 13:01:56 +02:00
/** \} */
Vulkan: Rewrite GHOST_ContextVK This is a rewrite of GHOST_ContextVK to align with Metal backend as described in #111389 - solution 3 with the adaptation that GHOST is still responsible for presenting the swap chain image and a post callback is still needed in case the swapchain is recreated. This PR also includes some smaller improvements in stability. Technical documentation: https://developer.blender.org/docs/eevee_and_viewport/gpu/vulkan/swap_chain/ * Renderpasses and framebuffers are not owned anymore by GHOST_ContextVK * VKFramebuffer doesn't contain a swap chain image. * Swapchain images can only be used as a blit destination or present source. Not as an attachment. * GHOST_ContextVK::swapBuffers would call a callback with the image the GPU module needs to blit the results to. * Clearing of depth/stencil attachments when no depth write state is set. * Enable VK_KHR_maintenance4 to relax the stage interface mapping. * Removes most vulkan validation warnings/errors. * Detection of frame buffer changes that needs to be applied before performing a command requiring render pass (draw/clear attachment) **Benefits** * Late retrieval of a swap chain image results in better overall performance as Blender doesn't need to wait until the image is presented on the screen. * Easier API and clearer state (transitions) * More control over Image layouts and command buffer states. (Better alignment with Vulkan API) Pull Request: https://projects.blender.org/blender/blender/pulls/111473
2023-08-29 15:05:08 +02:00
/* -------------------------------------------------------------------- */
/** \name Graphics pipeline
* \{ */
void VKContext::swap_buffer_acquired_callback()
Vulkan: Rewrite GHOST_ContextVK This is a rewrite of GHOST_ContextVK to align with Metal backend as described in #111389 - solution 3 with the adaptation that GHOST is still responsible for presenting the swap chain image and a post callback is still needed in case the swapchain is recreated. This PR also includes some smaller improvements in stability. Technical documentation: https://developer.blender.org/docs/eevee_and_viewport/gpu/vulkan/swap_chain/ * Renderpasses and framebuffers are not owned anymore by GHOST_ContextVK * VKFramebuffer doesn't contain a swap chain image. * Swapchain images can only be used as a blit destination or present source. Not as an attachment. * GHOST_ContextVK::swapBuffers would call a callback with the image the GPU module needs to blit the results to. * Clearing of depth/stencil attachments when no depth write state is set. * Enable VK_KHR_maintenance4 to relax the stage interface mapping. * Removes most vulkan validation warnings/errors. * Detection of frame buffer changes that needs to be applied before performing a command requiring render pass (draw/clear attachment) **Benefits** * Late retrieval of a swap chain image results in better overall performance as Blender doesn't need to wait until the image is presented on the screen. * Easier API and clearer state (transitions) * More control over Image layouts and command buffer states. (Better alignment with Vulkan API) Pull Request: https://projects.blender.org/blender/blender/pulls/111473
2023-08-29 15:05:08 +02:00
{
VKContext *context = VKContext::get();
BLI_assert(context);
context->swap_buffer_acquired_handler();
Vulkan: Rewrite GHOST_ContextVK This is a rewrite of GHOST_ContextVK to align with Metal backend as described in #111389 - solution 3 with the adaptation that GHOST is still responsible for presenting the swap chain image and a post callback is still needed in case the swapchain is recreated. This PR also includes some smaller improvements in stability. Technical documentation: https://developer.blender.org/docs/eevee_and_viewport/gpu/vulkan/swap_chain/ * Renderpasses and framebuffers are not owned anymore by GHOST_ContextVK * VKFramebuffer doesn't contain a swap chain image. * Swapchain images can only be used as a blit destination or present source. Not as an attachment. * GHOST_ContextVK::swapBuffers would call a callback with the image the GPU module needs to blit the results to. * Clearing of depth/stencil attachments when no depth write state is set. * Enable VK_KHR_maintenance4 to relax the stage interface mapping. * Removes most vulkan validation warnings/errors. * Detection of frame buffer changes that needs to be applied before performing a command requiring render pass (draw/clear attachment) **Benefits** * Late retrieval of a swap chain image results in better overall performance as Blender doesn't need to wait until the image is presented on the screen. * Easier API and clearer state (transitions) * More control over Image layouts and command buffer states. (Better alignment with Vulkan API) Pull Request: https://projects.blender.org/blender/blender/pulls/111473
2023-08-29 15:05:08 +02:00
}
void VKContext::swap_buffer_draw_callback(const GHOST_VulkanSwapChainData *swap_chain_data)
Vulkan: Rewrite GHOST_ContextVK This is a rewrite of GHOST_ContextVK to align with Metal backend as described in #111389 - solution 3 with the adaptation that GHOST is still responsible for presenting the swap chain image and a post callback is still needed in case the swapchain is recreated. This PR also includes some smaller improvements in stability. Technical documentation: https://developer.blender.org/docs/eevee_and_viewport/gpu/vulkan/swap_chain/ * Renderpasses and framebuffers are not owned anymore by GHOST_ContextVK * VKFramebuffer doesn't contain a swap chain image. * Swapchain images can only be used as a blit destination or present source. Not as an attachment. * GHOST_ContextVK::swapBuffers would call a callback with the image the GPU module needs to blit the results to. * Clearing of depth/stencil attachments when no depth write state is set. * Enable VK_KHR_maintenance4 to relax the stage interface mapping. * Removes most vulkan validation warnings/errors. * Detection of frame buffer changes that needs to be applied before performing a command requiring render pass (draw/clear attachment) **Benefits** * Late retrieval of a swap chain image results in better overall performance as Blender doesn't need to wait until the image is presented on the screen. * Easier API and clearer state (transitions) * More control over Image layouts and command buffer states. (Better alignment with Vulkan API) Pull Request: https://projects.blender.org/blender/blender/pulls/111473
2023-08-29 15:05:08 +02:00
{
VKContext *context = VKContext::get();
BLI_assert(context);
context->swap_buffer_draw_handler(*swap_chain_data);
Vulkan: Rewrite GHOST_ContextVK This is a rewrite of GHOST_ContextVK to align with Metal backend as described in #111389 - solution 3 with the adaptation that GHOST is still responsible for presenting the swap chain image and a post callback is still needed in case the swapchain is recreated. This PR also includes some smaller improvements in stability. Technical documentation: https://developer.blender.org/docs/eevee_and_viewport/gpu/vulkan/swap_chain/ * Renderpasses and framebuffers are not owned anymore by GHOST_ContextVK * VKFramebuffer doesn't contain a swap chain image. * Swapchain images can only be used as a blit destination or present source. Not as an attachment. * GHOST_ContextVK::swapBuffers would call a callback with the image the GPU module needs to blit the results to. * Clearing of depth/stencil attachments when no depth write state is set. * Enable VK_KHR_maintenance4 to relax the stage interface mapping. * Removes most vulkan validation warnings/errors. * Detection of frame buffer changes that needs to be applied before performing a command requiring render pass (draw/clear attachment) **Benefits** * Late retrieval of a swap chain image results in better overall performance as Blender doesn't need to wait until the image is presented on the screen. * Easier API and clearer state (transitions) * More control over Image layouts and command buffer states. (Better alignment with Vulkan API) Pull Request: https://projects.blender.org/blender/blender/pulls/111473
2023-08-29 15:05:08 +02:00
}
void VKContext::swap_buffer_acquired_handler()
{
sync_backbuffer();
}
void VKContext::swap_buffer_draw_handler(const GHOST_VulkanSwapChainData &swap_chain_data)
Vulkan: Rewrite GHOST_ContextVK This is a rewrite of GHOST_ContextVK to align with Metal backend as described in #111389 - solution 3 with the adaptation that GHOST is still responsible for presenting the swap chain image and a post callback is still needed in case the swapchain is recreated. This PR also includes some smaller improvements in stability. Technical documentation: https://developer.blender.org/docs/eevee_and_viewport/gpu/vulkan/swap_chain/ * Renderpasses and framebuffers are not owned anymore by GHOST_ContextVK * VKFramebuffer doesn't contain a swap chain image. * Swapchain images can only be used as a blit destination or present source. Not as an attachment. * GHOST_ContextVK::swapBuffers would call a callback with the image the GPU module needs to blit the results to. * Clearing of depth/stencil attachments when no depth write state is set. * Enable VK_KHR_maintenance4 to relax the stage interface mapping. * Removes most vulkan validation warnings/errors. * Detection of frame buffer changes that needs to be applied before performing a command requiring render pass (draw/clear attachment) **Benefits** * Late retrieval of a swap chain image results in better overall performance as Blender doesn't need to wait until the image is presented on the screen. * Easier API and clearer state (transitions) * More control over Image layouts and command buffer states. (Better alignment with Vulkan API) Pull Request: https://projects.blender.org/blender/blender/pulls/111473
2023-08-29 15:05:08 +02:00
{
const bool do_blit_to_swapchain = swap_chain_data.image != VK_NULL_HANDLE;
const bool use_shader = swap_chain_data.surface_format.colorSpace ==
VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT;
/* When swapchain is invalid/minimized we only flush the render graph to free GPU resources. */
if (!do_blit_to_swapchain) {
flush_render_graph(RenderGraphFlushFlags::SUBMIT | RenderGraphFlushFlags::RENEW_RENDER_GRAPH);
return;
}
Vulkan: Rewrite GHOST_ContextVK This is a rewrite of GHOST_ContextVK to align with Metal backend as described in #111389 - solution 3 with the adaptation that GHOST is still responsible for presenting the swap chain image and a post callback is still needed in case the swapchain is recreated. This PR also includes some smaller improvements in stability. Technical documentation: https://developer.blender.org/docs/eevee_and_viewport/gpu/vulkan/swap_chain/ * Renderpasses and framebuffers are not owned anymore by GHOST_ContextVK * VKFramebuffer doesn't contain a swap chain image. * Swapchain images can only be used as a blit destination or present source. Not as an attachment. * GHOST_ContextVK::swapBuffers would call a callback with the image the GPU module needs to blit the results to. * Clearing of depth/stencil attachments when no depth write state is set. * Enable VK_KHR_maintenance4 to relax the stage interface mapping. * Removes most vulkan validation warnings/errors. * Detection of frame buffer changes that needs to be applied before performing a command requiring render pass (draw/clear attachment) **Benefits** * Late retrieval of a swap chain image results in better overall performance as Blender doesn't need to wait until the image is presented on the screen. * Easier API and clearer state (transitions) * More control over Image layouts and command buffer states. (Better alignment with Vulkan API) Pull Request: https://projects.blender.org/blender/blender/pulls/111473
2023-08-29 15:05:08 +02:00
VKDevice &device = VKBackend::get().device;
render_graph::VKRenderGraph &render_graph = this->render_graph();
VKFrameBuffer &framebuffer = *unwrap(active_fb);
framebuffer.rendering_end(*this);
VKTexture *color_attachment = unwrap(unwrap(framebuffer.color_tex(0)));
device.resources.add_image(swap_chain_data.image, 1, "SwapchainImage");
GPU_debug_group_begin("BackBuffer.Blit");
if (use_shader) {
VKTexture swap_chain_texture("swap_chain_texture");
swap_chain_texture.init_swapchain(swap_chain_data.image,
to_gpu_format(swap_chain_data.surface_format.format));
Shader *shader = device.vk_backbuffer_blit_sh_get();
GPU_shader_bind(shader);
GPU_shader_uniform_1f(shader, "sdr_scale", swap_chain_data.sdr_scale);
/* See display_as_extended_srgb in libocio_display_processor.cc for details on this choice. */
#if defined(_WIN32) || defined(__APPLE__)
GPU_shader_uniform_1b(shader, "use_gamma22", false);
#else
GPU_shader_uniform_1b(shader, "use_gamma22", true);
#endif
VKStateManager &state_manager = state_manager_get();
state_manager.image_bind(color_attachment, 0);
state_manager.image_bind(&swap_chain_texture, 1);
int2 dispatch_size = math::divide_ceil(
int2(swap_chain_data.extent.width, swap_chain_data.extent.height), int2(16));
VKBackend::get().compute_dispatch(UNPACK2(dispatch_size), 1);
}
else {
render_graph::VKBlitImageNode::CreateInfo blit_image = {};
blit_image.src_image = color_attachment->vk_image_handle();
blit_image.dst_image = swap_chain_data.image;
blit_image.filter = VK_FILTER_LINEAR;
VkImageBlit &region = blit_image.region;
region.srcOffsets[0] = {0, 0, 0};
region.srcOffsets[1] = {color_attachment->width_get(), color_attachment->height_get(), 1};
region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.srcSubresource.mipLevel = 0;
region.srcSubresource.baseArrayLayer = 0;
region.srcSubresource.layerCount = 1;
region.dstOffsets[0] = {0, int32_t(swap_chain_data.extent.height), 0};
region.dstOffsets[1] = {int32_t(swap_chain_data.extent.width), 0, 1};
region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.dstSubresource.mipLevel = 0;
region.dstSubresource.baseArrayLayer = 0;
region.dstSubresource.layerCount = 1;
render_graph.add_node(blit_image);
}
Vulkan: Device command builder This PR implements a new the threading model for building render graphs based on tests performed last month. For out workload multithreaded command building will block in the driver or device. So better to use a single thread for command building. Details of the internal working is documented at https://developer.blender.org/docs/features/gpu/vulkan/render_graph/ - When a context is activated on a thread the context asks for a render graph it can use by calling `VKDevice::render_graph_new`. - Parts of the GPU backend that requires GPU commands will add a specific render graph node to the render graph. The nodes also contains a reference to all resources it needs including the access it needs and the image layout. - When the context is flushed the render graph is submitted to the device by calling `VKDevice::render_graph_submit`. - The device puts the render graph in `VKDevice::submission_pool`. - There is a single background thread that gets the next render graph to send to the GPU (`VKDevice::submission_runner`). - Reorder the commands of the render graph to comply with Vulkan specific command order rules and reducing possible bottlenecks. (`VKScheduler`) - Generate the required barriers `VKCommandBuilder::groups_extract_barriers`. This is a separate step to reduce resource locking giving other threads access to the resource states when they are building the render graph nodes. - GPU commands and pipeline barriers are recorded to a VkCommandBuffer. (`VKCommandBuilder::record_commands`) - When completed the command buffer can be submitted to the device queue. `vkQueueSubmit` - Render graphs that have been submitted can be reused by a next thread. This is done by pushing the render graph to the `VKDevice::unused_render_graphs` queue. Pull Request: https://projects.blender.org/blender/blender/pulls/132681
2025-01-27 08:55:23 +01:00
render_graph::VKSynchronizationNode::CreateInfo synchronization = {};
synchronization.vk_image = swap_chain_data.image;
synchronization.vk_image_layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
synchronization.vk_image_aspect = VK_IMAGE_ASPECT_COLOR_BIT;
render_graph.add_node(synchronization);
GPU_debug_group_end();
flush_render_graph(RenderGraphFlushFlags::SUBMIT | RenderGraphFlushFlags::RENEW_RENDER_GRAPH,
VK_PIPELINE_STAGE_TRANSFER_BIT,
swap_chain_data.acquire_semaphore,
swap_chain_data.present_semaphore,
swap_chain_data.submission_fence);
Vulkan: Device command builder This PR implements a new the threading model for building render graphs based on tests performed last month. For out workload multithreaded command building will block in the driver or device. So better to use a single thread for command building. Details of the internal working is documented at https://developer.blender.org/docs/features/gpu/vulkan/render_graph/ - When a context is activated on a thread the context asks for a render graph it can use by calling `VKDevice::render_graph_new`. - Parts of the GPU backend that requires GPU commands will add a specific render graph node to the render graph. The nodes also contains a reference to all resources it needs including the access it needs and the image layout. - When the context is flushed the render graph is submitted to the device by calling `VKDevice::render_graph_submit`. - The device puts the render graph in `VKDevice::submission_pool`. - There is a single background thread that gets the next render graph to send to the GPU (`VKDevice::submission_runner`). - Reorder the commands of the render graph to comply with Vulkan specific command order rules and reducing possible bottlenecks. (`VKScheduler`) - Generate the required barriers `VKCommandBuilder::groups_extract_barriers`. This is a separate step to reduce resource locking giving other threads access to the resource states when they are building the render graph nodes. - GPU commands and pipeline barriers are recorded to a VkCommandBuffer. (`VKCommandBuilder::record_commands`) - When completed the command buffer can be submitted to the device queue. `vkQueueSubmit` - Render graphs that have been submitted can be reused by a next thread. This is done by pushing the render graph to the `VKDevice::unused_render_graphs` queue. Pull Request: https://projects.blender.org/blender/blender/pulls/132681
2025-01-27 08:55:23 +01:00
device.resources.remove_image(swap_chain_data.image);
#if 0
device.debug_print();
#endif
Vulkan: Rewrite GHOST_ContextVK This is a rewrite of GHOST_ContextVK to align with Metal backend as described in #111389 - solution 3 with the adaptation that GHOST is still responsible for presenting the swap chain image and a post callback is still needed in case the swapchain is recreated. This PR also includes some smaller improvements in stability. Technical documentation: https://developer.blender.org/docs/eevee_and_viewport/gpu/vulkan/swap_chain/ * Renderpasses and framebuffers are not owned anymore by GHOST_ContextVK * VKFramebuffer doesn't contain a swap chain image. * Swapchain images can only be used as a blit destination or present source. Not as an attachment. * GHOST_ContextVK::swapBuffers would call a callback with the image the GPU module needs to blit the results to. * Clearing of depth/stencil attachments when no depth write state is set. * Enable VK_KHR_maintenance4 to relax the stage interface mapping. * Removes most vulkan validation warnings/errors. * Detection of frame buffer changes that needs to be applied before performing a command requiring render pass (draw/clear attachment) **Benefits** * Late retrieval of a swap chain image results in better overall performance as Blender doesn't need to wait until the image is presented on the screen. * Easier API and clearer state (transitions) * More control over Image layouts and command buffer states. (Better alignment with Vulkan API) Pull Request: https://projects.blender.org/blender/blender/pulls/111473
2023-08-29 15:05:08 +02:00
}
void VKContext::specialization_constants_set(
const shader::SpecializationConstants *constants_state)
{
constants_state_ = (constants_state != nullptr) ? *constants_state :
shader::SpecializationConstants{};
}
Vulkan: Rewrite GHOST_ContextVK This is a rewrite of GHOST_ContextVK to align with Metal backend as described in #111389 - solution 3 with the adaptation that GHOST is still responsible for presenting the swap chain image and a post callback is still needed in case the swapchain is recreated. This PR also includes some smaller improvements in stability. Technical documentation: https://developer.blender.org/docs/eevee_and_viewport/gpu/vulkan/swap_chain/ * Renderpasses and framebuffers are not owned anymore by GHOST_ContextVK * VKFramebuffer doesn't contain a swap chain image. * Swapchain images can only be used as a blit destination or present source. Not as an attachment. * GHOST_ContextVK::swapBuffers would call a callback with the image the GPU module needs to blit the results to. * Clearing of depth/stencil attachments when no depth write state is set. * Enable VK_KHR_maintenance4 to relax the stage interface mapping. * Removes most vulkan validation warnings/errors. * Detection of frame buffer changes that needs to be applied before performing a command requiring render pass (draw/clear attachment) **Benefits** * Late retrieval of a swap chain image results in better overall performance as Blender doesn't need to wait until the image is presented on the screen. * Easier API and clearer state (transitions) * More control over Image layouts and command buffer states. (Better alignment with Vulkan API) Pull Request: https://projects.blender.org/blender/blender/pulls/111473
2023-08-29 15:05:08 +02:00
/** \} */
Vulkan: Initial OpenXR support The Blender's VkInstance cannot be shared with OpenXR VkInstance. The reason is a chicken and egg problem where OpenXR needs to be started before Vulkan. OpenXR can add special vulkan specific requirements (instance&device) that are only available when the user starts an OpenXR session. The goal implementation is to share memory between both instances using [VK_KHR_external_memory](https://registry.khronos.org/vulkan/specs/latest/man/html/VK_KHR_external_memory.html) and related extensions. However this seems to be a bridge to far as a initial step. Reason: There are not that many samples/ guides and documentation to be found to handle the workflow that we require. We want to do a smaller step by step approach to gain the needed knowledge. For that reason this PR does the most stupidest thing that can be done to share memory between instances. Download the render result to CPU RAM share the host pointer with the OpenXR instance which copies it to the swap chain. Also the synchronization is done using wait idle commands. <video src="attachments/32a0d69b-c3fa-4272-aea0-d207609afaaf" title="Screencast From 2025-03-18 11-16-17.webm" controls></video> **Gaining knowledge** - Experiment with `VK_KHR_external_memory_host` extension for uploading vertex buffers (not related to OpenXR). - Import host pointer with `VK_KHR_external_memory_host`. This reduces the additional memcpy on OpenXR side. - Export host pointer from Blender side from a mappable buffer. - Replace host pointers with fd/dmabuf/winhandle - Remove mappable buffer. Ref #133718 Pull Request: https://projects.blender.org/blender/blender/pulls/133824
2025-03-27 16:57:51 +01:00
/* -------------------------------------------------------------------- */
/** \name OpenXR
* \{ */
void VKContext::openxr_acquire_framebuffer_image_callback(GHOST_VulkanOpenXRData *openxr_data)
{
VKContext *context = VKContext::get();
BLI_assert(context);
context->openxr_acquire_framebuffer_image_handler(*openxr_data);
}
void VKContext::openxr_release_framebuffer_image_callback(GHOST_VulkanOpenXRData *openxr_data)
{
VKContext *context = VKContext::get();
BLI_assert(context);
context->openxr_release_framebuffer_image_handler(*openxr_data);
}
void VKContext::openxr_acquire_framebuffer_image_handler(GHOST_VulkanOpenXRData &openxr_data)
{
VKFrameBuffer &framebuffer = *unwrap(active_fb);
VKTexture *color_attachment = unwrap(unwrap(framebuffer.color_tex(0)));
openxr_data.extent.width = color_attachment->width_get();
openxr_data.extent.height = color_attachment->height_get();
/* Determine the data format for data transfer. */
const TextureFormat device_format = color_attachment->device_format_get();
eGPUDataFormat data_format = GPU_DATA_HALF_FLOAT;
if (ELEM(device_format, TextureFormat::UNORM_8_8_8_8)) {
data_format = GPU_DATA_UBYTE;
}
switch (openxr_data.data_transfer_mode) {
case GHOST_kVulkanXRModeCPU:
openxr_data.cpu.image_data = color_attachment->read(0, data_format);
break;
case GHOST_kVulkanXRModeFD: {
flush_render_graph(RenderGraphFlushFlags::SUBMIT |
RenderGraphFlushFlags::WAIT_FOR_COMPLETION |
RenderGraphFlushFlags::RENEW_RENDER_GRAPH);
if (openxr_data.gpu.vk_image_blender != color_attachment->vk_image_handle()) {
VKMemoryExport exported_memory = color_attachment->export_memory(
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);
openxr_data.gpu.image_handle = exported_memory.handle;
openxr_data.gpu.new_handle = true;
openxr_data.gpu.image_format = to_vk_format(color_attachment->device_format_get());
openxr_data.gpu.memory_size = exported_memory.memory_size;
openxr_data.gpu.memory_offset = exported_memory.memory_offset;
openxr_data.gpu.vk_image_blender = color_attachment->vk_image_handle();
}
break;
}
case GHOST_kVulkanXRModeWin32: {
flush_render_graph(RenderGraphFlushFlags::SUBMIT |
RenderGraphFlushFlags::WAIT_FOR_COMPLETION |
RenderGraphFlushFlags::RENEW_RENDER_GRAPH);
if (openxr_data.gpu.vk_image_blender != color_attachment->vk_image_handle()) {
VKMemoryExport exported_memory = color_attachment->export_memory(
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT);
openxr_data.gpu.image_handle = exported_memory.handle;
openxr_data.gpu.new_handle = true;
openxr_data.gpu.image_format = to_vk_format(color_attachment->device_format_get());
openxr_data.gpu.memory_size = exported_memory.memory_size;
openxr_data.gpu.memory_offset = exported_memory.memory_offset;
openxr_data.gpu.vk_image_blender = color_attachment->vk_image_handle();
}
break;
}
}
Vulkan: Initial OpenXR support The Blender's VkInstance cannot be shared with OpenXR VkInstance. The reason is a chicken and egg problem where OpenXR needs to be started before Vulkan. OpenXR can add special vulkan specific requirements (instance&device) that are only available when the user starts an OpenXR session. The goal implementation is to share memory between both instances using [VK_KHR_external_memory](https://registry.khronos.org/vulkan/specs/latest/man/html/VK_KHR_external_memory.html) and related extensions. However this seems to be a bridge to far as a initial step. Reason: There are not that many samples/ guides and documentation to be found to handle the workflow that we require. We want to do a smaller step by step approach to gain the needed knowledge. For that reason this PR does the most stupidest thing that can be done to share memory between instances. Download the render result to CPU RAM share the host pointer with the OpenXR instance which copies it to the swap chain. Also the synchronization is done using wait idle commands. <video src="attachments/32a0d69b-c3fa-4272-aea0-d207609afaaf" title="Screencast From 2025-03-18 11-16-17.webm" controls></video> **Gaining knowledge** - Experiment with `VK_KHR_external_memory_host` extension for uploading vertex buffers (not related to OpenXR). - Import host pointer with `VK_KHR_external_memory_host`. This reduces the additional memcpy on OpenXR side. - Export host pointer from Blender side from a mappable buffer. - Replace host pointers with fd/dmabuf/winhandle - Remove mappable buffer. Ref #133718 Pull Request: https://projects.blender.org/blender/blender/pulls/133824
2025-03-27 16:57:51 +01:00
}
void VKContext::openxr_release_framebuffer_image_handler(GHOST_VulkanOpenXRData &openxr_data)
{
switch (openxr_data.data_transfer_mode) {
case GHOST_kVulkanXRModeCPU:
MEM_freeN(openxr_data.cpu.image_data);
openxr_data.cpu.image_data = nullptr;
break;
case GHOST_kVulkanXRModeFD:
/* Nothing to do as import of the handle by the XrInstance removes the ownership of the
* handle. Ref
* https://registry.khronos.org/vulkan/specs/latest/man/html/VK_KHR_external_memory_fd.html#_issues
*/
break;
case GHOST_kVulkanXRModeWin32:
#ifdef _WIN32
if (openxr_data.gpu.new_handle) {
/* Exported handle isn't consumed during import and should be freed after use. */
CloseHandle(HANDLE(openxr_data.gpu.image_handle));
openxr_data.gpu.image_handle = 0;
}
#endif
break;
}
Vulkan: Initial OpenXR support The Blender's VkInstance cannot be shared with OpenXR VkInstance. The reason is a chicken and egg problem where OpenXR needs to be started before Vulkan. OpenXR can add special vulkan specific requirements (instance&device) that are only available when the user starts an OpenXR session. The goal implementation is to share memory between both instances using [VK_KHR_external_memory](https://registry.khronos.org/vulkan/specs/latest/man/html/VK_KHR_external_memory.html) and related extensions. However this seems to be a bridge to far as a initial step. Reason: There are not that many samples/ guides and documentation to be found to handle the workflow that we require. We want to do a smaller step by step approach to gain the needed knowledge. For that reason this PR does the most stupidest thing that can be done to share memory between instances. Download the render result to CPU RAM share the host pointer with the OpenXR instance which copies it to the swap chain. Also the synchronization is done using wait idle commands. <video src="attachments/32a0d69b-c3fa-4272-aea0-d207609afaaf" title="Screencast From 2025-03-18 11-16-17.webm" controls></video> **Gaining knowledge** - Experiment with `VK_KHR_external_memory_host` extension for uploading vertex buffers (not related to OpenXR). - Import host pointer with `VK_KHR_external_memory_host`. This reduces the additional memcpy on OpenXR side. - Export host pointer from Blender side from a mappable buffer. - Replace host pointers with fd/dmabuf/winhandle - Remove mappable buffer. Ref #133718 Pull Request: https://projects.blender.org/blender/blender/pulls/133824
2025-03-27 16:57:51 +01:00
}
/** \} */
2023-01-31 15:49:04 +11:00
} // namespace blender::gpu