Update the `ShaderCompilerGeneric` to support deferred compilation using the batch compilation API, so we can get rid of `drw_manager_shader`. This approach also allows supporting non-blocking compilation for static shaders. This shouldn't cause any behavior changes at the moment, since batch compilation is not yet used when parallel compilation is disabled. This adds a `GPUWorker` and a `GPUSecondaryContext` as an easy to use wrapper for managing secondary GPU contexts. (Part of #133674) Pull Request: https://projects.blender.org/blender/blender/pulls/136518
155 lines
4.6 KiB
C++
155 lines
4.6 KiB
C++
/* SPDX-FileCopyrightText: 2022 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup gpu
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "BLI_utildefines.h"
|
|
|
|
#include "gpu_context_private.hh"
|
|
|
|
#include "GHOST_Types.h"
|
|
|
|
#include "render_graph/vk_render_graph.hh"
|
|
#include "vk_common.hh"
|
|
#include "vk_debug.hh"
|
|
#include "vk_descriptor_pools.hh"
|
|
#include "vk_resource_pool.hh"
|
|
|
|
namespace blender::gpu {
|
|
class VKFrameBuffer;
|
|
class VKVertexAttributeObject;
|
|
class VKBatch;
|
|
class VKStateManager;
|
|
class VKShader;
|
|
class VKThreadData;
|
|
|
|
enum RenderGraphFlushFlags {
|
|
NONE = 0,
|
|
RENEW_RENDER_GRAPH = 1 << 0,
|
|
SUBMIT = 1 << 1,
|
|
WAIT_FOR_COMPLETION = 1 << 2,
|
|
};
|
|
ENUM_OPERATORS(RenderGraphFlushFlags, RenderGraphFlushFlags::WAIT_FOR_COMPLETION);
|
|
|
|
class VKContext : public Context, NonCopyable {
|
|
private:
|
|
VkExtent2D vk_extent_ = {};
|
|
VkSurfaceFormatKHR swap_chain_format_ = {};
|
|
GPUTexture *surface_texture_ = nullptr;
|
|
void *ghost_context_;
|
|
|
|
/* Reusable data. Stored inside context to limit reallocations. */
|
|
render_graph::VKResourceAccessInfo access_info_ = {};
|
|
|
|
std::optional<std::reference_wrapper<VKThreadData>> thread_data_;
|
|
std::optional<std::reference_wrapper<render_graph::VKRenderGraph>> render_graph_;
|
|
|
|
public:
|
|
VKDiscardPool discard_pool;
|
|
|
|
const render_graph::VKRenderGraph &render_graph() const
|
|
{
|
|
return render_graph_.value().get();
|
|
}
|
|
render_graph::VKRenderGraph &render_graph()
|
|
{
|
|
return render_graph_.value().get();
|
|
}
|
|
|
|
VKContext(void *ghost_window, void *ghost_context);
|
|
virtual ~VKContext();
|
|
|
|
void activate() override;
|
|
void deactivate() override;
|
|
void begin_frame() override;
|
|
void end_frame() override;
|
|
|
|
void flush() override;
|
|
|
|
TimelineValue flush_render_graph(
|
|
RenderGraphFlushFlags flags,
|
|
VkPipelineStageFlags wait_dst_stage_mask = VK_PIPELINE_STAGE_NONE,
|
|
VkSemaphore wait_semaphore = VK_NULL_HANDLE,
|
|
VkSemaphore signal_semaphore = VK_NULL_HANDLE,
|
|
VkFence signal_fence = VK_NULL_HANDLE);
|
|
void finish() override;
|
|
|
|
ShaderCompiler *get_compiler() override;
|
|
|
|
void memory_statistics_get(int *r_total_mem_kb, int *r_free_mem_kb) override;
|
|
|
|
void debug_group_begin(const char *, int) override;
|
|
void debug_group_end() override;
|
|
bool debug_capture_begin(const char *title) override;
|
|
void debug_capture_end() override;
|
|
void *debug_capture_scope_create(const char *name) override;
|
|
bool debug_capture_scope_begin(void *scope) override;
|
|
void debug_capture_scope_end(void *scope) override;
|
|
|
|
void debug_unbind_all_ubo() override;
|
|
void debug_unbind_all_ssbo() override;
|
|
|
|
bool has_active_framebuffer() const;
|
|
void activate_framebuffer(VKFrameBuffer &framebuffer);
|
|
void deactivate_framebuffer();
|
|
VKFrameBuffer *active_framebuffer_get() const;
|
|
|
|
/**
|
|
* Ensure that the active framebuffer isn't rendering.
|
|
*
|
|
* Between `vkCmdBeginRendering` and `vkCmdEndRendering` the framebuffer is rendering. Dispatch
|
|
* and transfer commands cannot be called between these commands. They can call this method to
|
|
* ensure that the framebuffer is outside these calls.
|
|
*/
|
|
void rendering_end();
|
|
|
|
render_graph::VKResourceAccessInfo &reset_and_get_access_info();
|
|
|
|
/**
|
|
* Update the give shader data with the current state of the context.
|
|
*/
|
|
void update_pipeline_data(render_graph::VKPipelineData &r_pipeline_data);
|
|
void update_pipeline_data(GPUPrimType primitive,
|
|
VKVertexAttributeObject &vao,
|
|
render_graph::VKPipelineData &r_pipeline_data);
|
|
|
|
void sync_backbuffer(bool cycle_resource_pool);
|
|
|
|
static VKContext *get()
|
|
{
|
|
return static_cast<VKContext *>(Context::get());
|
|
}
|
|
|
|
VKDescriptorPools &descriptor_pools_get();
|
|
VKDescriptorSetTracker &descriptor_set_get();
|
|
VKStateManager &state_manager_get() const;
|
|
|
|
static void swap_buffers_pre_callback(const GHOST_VulkanSwapChainData *data);
|
|
static void swap_buffers_post_callback();
|
|
static void openxr_acquire_framebuffer_image_callback(GHOST_VulkanOpenXRData *data);
|
|
static void openxr_release_framebuffer_image_callback(GHOST_VulkanOpenXRData *data);
|
|
|
|
private:
|
|
void swap_buffers_pre_handler(const GHOST_VulkanSwapChainData &data);
|
|
void swap_buffers_post_handler();
|
|
|
|
void openxr_acquire_framebuffer_image_handler(GHOST_VulkanOpenXRData &data);
|
|
void openxr_release_framebuffer_image_handler(GHOST_VulkanOpenXRData &data);
|
|
|
|
void update_pipeline_data(VKShader &shader,
|
|
VkPipeline vk_pipeline,
|
|
render_graph::VKPipelineData &r_pipeline_data);
|
|
};
|
|
|
|
BLI_INLINE bool operator==(const VKContext &a, const VKContext &b)
|
|
{
|
|
return static_cast<const void *>(&a) == static_cast<const void *>(&b);
|
|
}
|
|
|
|
} // namespace blender::gpu
|