This PR introduces parallel shader compilation for Vulkan shader modules. This will improve shader compilation when switching to material preview or EEVEE render preview. It also improves material compilation. However in order to measure the differences shaderc needs to be updated. PR has been created so we can already start with the code review. This PR doesn't include SPIR-V caching, what will land in a separate PR as it needs more validation. Parallel shader compilation has been tested on AMD/NVIDIA on Linux. Testing on other platforms is planned in the upcoming days. **Performance** ``` AMD Ryzen™ 9 7950X × 32, 64GB Ram Operating system: Linux-6.8.0-44-generic-x86_64-with-glibc2.39 64 Bits, X11 UI Graphics card: Quadro RTX 6000/PCIe/SSE2 NVIDIA Corporation 4.6.0 NVIDIA 550.107.02 ``` *Test*: Start blender, open barbershop_interior.blend and wait until the viewport has fully settled. | Backend | Test | Duration | | ------- | ------------------------- | -------- | | OpenGL | Coldstart/No subprocesses | 1:52 | | OpenGL | Coldstart/8 Subprocesses | 0:54 | | OpenGL | Warmstart/8 Subprocesses | 0:06 | | Vulkan | Coldstart Without PR | 0:59 | | Vulkan | Warmstart Without PR | 0:58 | | Vulkan | Coldstart With PR | 0:33 | | Vulkan | Warmstart With PR | 0:08 | The difference in time (why OpenGL is faster in a warm start is that all shaders are cached). Vulkan in this case doesn't cache anything and all shaders are recompiled each time. Caching the shaders will be part of a future PR. Main reason not to add it to this PR directly is that SPIR-V cannot easily be validated and would require a sidecar to keep SPIR-V compatible with external tools.. **NOTE**: - This PR was extracted from #127418 - This PR requires #127564 to land and libraries to update. Linux lib is available as attachment in this PR. It works without, but is as slow as single threaded compilation. Pull Request: https://projects.blender.org/blender/blender/pulls/127698
109 lines
2.8 KiB
C++
109 lines
2.8 KiB
C++
/* SPDX-FileCopyrightText: 2022 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup gpu
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "gpu_backend.hh"
|
|
|
|
#ifdef WITH_RENDERDOC
|
|
# include "renderdoc_api.hh"
|
|
#endif
|
|
|
|
#include "vk_common.hh"
|
|
#include "vk_device.hh"
|
|
#include "vk_shader_compiler.hh"
|
|
|
|
namespace blender::gpu {
|
|
|
|
class VKContext;
|
|
class VKDescriptorSet;
|
|
class VKDescriptorSetTracker;
|
|
|
|
class VKBackend : public GPUBackend {
|
|
private:
|
|
#ifdef WITH_RENDERDOC
|
|
renderdoc::api::Renderdoc renderdoc_api_;
|
|
#endif
|
|
|
|
public:
|
|
VKShaderCompiler shader_compiler;
|
|
/* Global instance to device handles. */
|
|
VKDevice device;
|
|
|
|
VKBackend()
|
|
{
|
|
platform_init();
|
|
}
|
|
|
|
virtual ~VKBackend()
|
|
{
|
|
VKBackend::platform_exit();
|
|
}
|
|
|
|
/**
|
|
* Does the running platform contain any device that meets the minimum requirements to start the
|
|
* Vulkan backend.
|
|
*
|
|
* Function is used to validate that a Blender UI can be started. It calls vulkan API commands
|
|
* directly to ensure no parts of Blender needs to be initialized.
|
|
*/
|
|
static bool is_supported();
|
|
|
|
void delete_resources() override;
|
|
|
|
void samplers_update() override;
|
|
void compute_dispatch(int groups_x_len, int groups_y_len, int groups_z_len) override;
|
|
void compute_dispatch_indirect(StorageBuf *indirect_buf) override;
|
|
|
|
Context *context_alloc(void *ghost_window, void *ghost_context) override;
|
|
|
|
Batch *batch_alloc() override;
|
|
DrawList *drawlist_alloc(int list_length) override;
|
|
Fence *fence_alloc() override;
|
|
FrameBuffer *framebuffer_alloc(const char *name) override;
|
|
IndexBuf *indexbuf_alloc() override;
|
|
PixelBuffer *pixelbuf_alloc(size_t size) override;
|
|
QueryPool *querypool_alloc() override;
|
|
Shader *shader_alloc(const char *name) override;
|
|
Texture *texture_alloc(const char *name) override;
|
|
UniformBuf *uniformbuf_alloc(size_t size, const char *name) override;
|
|
StorageBuf *storagebuf_alloc(size_t size, GPUUsageType usage, const char *name) override;
|
|
VertBuf *vertbuf_alloc() override;
|
|
|
|
void shader_cache_dir_clear_old() override {}
|
|
|
|
/* Render Frame Coordination --
|
|
* Used for performing per-frame actions globally */
|
|
void render_begin() override;
|
|
void render_end() override;
|
|
void render_step() override;
|
|
|
|
bool debug_capture_begin(const char *title);
|
|
void debug_capture_end();
|
|
|
|
static VKBackend &get()
|
|
{
|
|
return *static_cast<VKBackend *>(GPUBackend::get());
|
|
}
|
|
|
|
static void platform_init(const VKDevice &device);
|
|
static void capabilities_init(VKDevice &device);
|
|
|
|
private:
|
|
static void detect_workarounds(VKDevice &device);
|
|
static void platform_init();
|
|
static void platform_exit();
|
|
|
|
/* These classes are allowed to modify the global device. */
|
|
friend class VKContext;
|
|
friend class VKDescriptorSet;
|
|
friend class VKDescriptorSetTracker;
|
|
};
|
|
|
|
} // namespace blender::gpu
|