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
96 lines
3.4 KiB
C++
96 lines
3.4 KiB
C++
/* SPDX-License-Identifier: GPL-2.0-or-later
|
|
* Copyright 2022 Blender Foundation. All rights reserved. */
|
|
|
|
/** \file
|
|
* \ingroup gpu
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "gpu_shader_private.hh"
|
|
|
|
#include "vk_backend.hh"
|
|
#include "vk_context.hh"
|
|
|
|
#include "BLI_string_ref.hh"
|
|
|
|
namespace blender::gpu {
|
|
class VKShaderInterface;
|
|
|
|
class VKShader : public Shader {
|
|
private:
|
|
VKContext *context_ = nullptr;
|
|
VkShaderModule vertex_module_ = VK_NULL_HANDLE;
|
|
VkShaderModule geometry_module_ = VK_NULL_HANDLE;
|
|
VkShaderModule fragment_module_ = VK_NULL_HANDLE;
|
|
VkShaderModule compute_module_ = VK_NULL_HANDLE;
|
|
bool compilation_failed_ = false;
|
|
VkDescriptorSetLayout layout_ = VK_NULL_HANDLE;
|
|
VkPipelineLayout pipeline_layout_ = VK_NULL_HANDLE;
|
|
VKPipeline compute_pipeline_;
|
|
|
|
public:
|
|
VKShader(const char *name);
|
|
virtual ~VKShader();
|
|
|
|
void vertex_shader_from_glsl(MutableSpan<const char *> sources) override;
|
|
void geometry_shader_from_glsl(MutableSpan<const char *> sources) override;
|
|
void fragment_shader_from_glsl(MutableSpan<const char *> sources) override;
|
|
void compute_shader_from_glsl(MutableSpan<const char *> sources) override;
|
|
bool finalize(const shader::ShaderCreateInfo *info = nullptr) override;
|
|
void warm_cache(int limit) override;
|
|
|
|
void transform_feedback_names_set(Span<const char *> name_list,
|
|
eGPUShaderTFBType geom_type) override;
|
|
bool transform_feedback_enable(GPUVertBuf *) override;
|
|
void transform_feedback_disable() override;
|
|
|
|
void bind() override;
|
|
void unbind() override;
|
|
|
|
void uniform_float(int location, int comp_len, int array_size, const float *data) override;
|
|
void uniform_int(int location, int comp_len, int array_size, const int *data) override;
|
|
|
|
std::string resources_declare(const shader::ShaderCreateInfo &info) const override;
|
|
std::string vertex_interface_declare(const shader::ShaderCreateInfo &info) const override;
|
|
std::string fragment_interface_declare(const shader::ShaderCreateInfo &info) const override;
|
|
std::string geometry_interface_declare(const shader::ShaderCreateInfo &info) const override;
|
|
std::string geometry_layout_declare(const shader::ShaderCreateInfo &info) const override;
|
|
std::string compute_layout_declare(const shader::ShaderCreateInfo &info) const override;
|
|
|
|
/* DEPRECATED: Kept only because of BGL API. */
|
|
int program_handle_get() const override;
|
|
|
|
VKPipeline &pipeline_get();
|
|
VkPipelineLayout vk_pipeline_layout_get() const
|
|
{
|
|
return pipeline_layout_;
|
|
}
|
|
|
|
const VKShaderInterface &interface_get() const;
|
|
|
|
private:
|
|
Vector<uint32_t> compile_glsl_to_spirv(Span<const char *> sources, shaderc_shader_kind kind);
|
|
void build_shader_module(Span<uint32_t> spirv_module, VkShaderModule *r_shader_module);
|
|
void build_shader_module(MutableSpan<const char *> sources,
|
|
shaderc_shader_kind stage,
|
|
VkShaderModule *r_shader_module);
|
|
bool finalize_descriptor_set_layouts(VkDevice vk_device,
|
|
const VKShaderInterface &shader_interface,
|
|
const shader::ShaderCreateInfo &info);
|
|
bool finalize_pipeline_layout(VkDevice vk_device, const shader::ShaderCreateInfo &info);
|
|
bool finalize_graphics_pipeline(VkDevice vk_device);
|
|
|
|
bool is_graphics_shader() const
|
|
{
|
|
return !is_compute_shader();
|
|
}
|
|
|
|
bool is_compute_shader() const
|
|
{
|
|
return compute_module_ != VK_NULL_HANDLE;
|
|
}
|
|
};
|
|
|
|
} // namespace blender::gpu
|