[Bf-blender-cvs] [c124606d70d] tmp-vulkan: Vulkan: Compile Shader Modules.

Jeroen Bakker noreply at git.blender.org
Fri Jun 25 16:53:34 CEST 2021


Commit: c124606d70d57f1e9c12fb8af6ab7bc194830798
Author: Jeroen Bakker
Date:   Fri Jun 25 14:37:29 2021 +0200
Branches: tmp-vulkan
https://developer.blender.org/rBc124606d70d57f1e9c12fb8af6ab7bc194830798

Vulkan: Compile Shader Modules.

Shaders are expected to fail as they need to be converted to Vulkan. Dy default the compilation is turned off. Enable VULKAN_SHADER_COMPILATION to activate shader module compilation.

===================================================================

M	source/blender/gpu/CMakeLists.txt
A	source/blender/gpu/vulkan/vk_shader.cc
M	source/blender/gpu/vulkan/vk_shader.hh

===================================================================

diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index fe957a9cb8e..5ca7678f33e 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -207,6 +207,7 @@ if(WITH_VULKAN)
     vulkan/vk_context.cc
     vulkan/vk_framebuffer.cc
     vulkan/vk_texture.cc
+    vulkan/vk_shader.cc
 
     vulkan/vk_backend.hh
     vulkan/vk_batch.hh
diff --git a/source/blender/gpu/vulkan/vk_shader.cc b/source/blender/gpu/vulkan/vk_shader.cc
new file mode 100644
index 00000000000..9848e4835a2
--- /dev/null
+++ b/source/blender/gpu/vulkan/vk_shader.cc
@@ -0,0 +1,271 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2021 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "vk_shader.hh"
+
+#include <string>
+
+#include "BLI_vector.hh"
+
+#include "shader_compiler.hh"
+
+/* Enable when actually developing on the shader compilation. When disabled compilation
+ * will not be done. Allows development on other areas during migrating shaders.*/
+// #define VULKAN_SHADER_COMPILATION
+
+namespace blender::gpu {
+
+/* -------------------------------------------------------------------- */
+/** \name Shader stages
+ * \{ */
+
+constexpr StringRef SHADER_STAGE_VERTEX_SHADER = "vertex";
+constexpr StringRef SHADER_STAGE_GEOMETRY_SHADER = "geometry";
+constexpr StringRef SHADER_STAGE_FRAGMENT_SHADER = "fragment";
+constexpr StringRef SHADER_STAGE_COMPUTE_SHADER = "compute";
+
+std::ostream &operator<<(std::ostream &os, const VKShaderStageType &stage)
+{
+  switch (stage) {
+    case VKShaderStageType::VertexShader:
+      os << SHADER_STAGE_VERTEX_SHADER;
+      break;
+    case VKShaderStageType::GeometryShader:
+      os << SHADER_STAGE_GEOMETRY_SHADER;
+      break;
+    case VKShaderStageType::FragmentShader:
+      os << SHADER_STAGE_FRAGMENT_SHADER;
+      break;
+    case VKShaderStageType::ComputeShader:
+      os << SHADER_STAGE_COMPUTE_SHADER;
+      break;
+  }
+  return os;
+}
+
+static shader_compiler::SourceType to_source_type(VKShaderStageType stage)
+{
+  switch (stage) {
+    case VKShaderStageType::VertexShader:
+      return shader_compiler::SourceType::GlslVertexShader;
+      break;
+    case VKShaderStageType::GeometryShader:
+      return shader_compiler::SourceType::GlslGeometryShader;
+      break;
+    case VKShaderStageType::FragmentShader:
+      return shader_compiler::SourceType::GlslFragmentShader;
+      break;
+    case VKShaderStageType::ComputeShader:
+      return shader_compiler::SourceType::GlslComputeShader;
+      break;
+  }
+  BLI_assert(!"Unknown VKShaderStageType.");
+  return shader_compiler::SourceType::GlslVertexShader;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Construction/Destruction
+ * \{ */
+
+VKShader::VKShader(const char *name) : Shader(name)
+{
+  interface = new VKShaderInterface();
+  context_ = VKContext::get();
+};
+
+VKShader::~VKShader()
+{
+  VkDevice device = context_->device_get();
+  if (vertex_shader_ != VK_NULL_HANDLE) {
+    vkDestroyShaderModule(device, vertex_shader_, nullptr);
+    vertex_shader_ = VK_NULL_HANDLE;
+  }
+  if (geometry_shader_ != VK_NULL_HANDLE) {
+    vkDestroyShaderModule(device, geometry_shader_, nullptr);
+    geometry_shader_ = VK_NULL_HANDLE;
+  }
+  if (fragment_shader_ != VK_NULL_HANDLE) {
+    vkDestroyShaderModule(device, fragment_shader_, nullptr);
+    fragment_shader_ = VK_NULL_HANDLE;
+  }
+  if (compute_shader_ != VK_NULL_HANDLE) {
+    vkDestroyShaderModule(device, compute_shader_, nullptr);
+    compute_shader_ = VK_NULL_HANDLE;
+  }
+
+  delete interface;
+  context_ = nullptr;
+};
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Compilation
+ * \{ */
+
+static std::string to_stage_name(VKShaderStageType stage)
+{
+  std::stringstream ss;
+  ss << stage;
+  return ss.str();
+}
+
+static std::string to_stage_name(StringRef name, VKShaderStageType stage)
+{
+  std::stringstream ss;
+  ss << name << "." << stage;
+  return ss.str();
+}
+
+static std::string combine_sources(MutableSpan<const char *> sources)
+{
+  std::stringstream combined;
+  for (std::string source : sources) {
+    combined << source;
+  }
+  return combined.str();
+}
+
+std::unique_ptr<std::vector<uint32_t>> VKShader::compile_source(MutableSpan<const char *> sources,
+                                                                VKShaderStageType stage)
+{
+  std::string stage_name = to_stage_name(name, stage);
+  std::string source = combine_sources(sources);
+
+  shader_compiler::Compiler *compiler = shader_compiler::Compiler::create_default();
+  shader_compiler::Job job;
+
+  /* TODO(jbakker): Ugly! should change interface. */
+  job.name = std::string(name).c_str();
+  job.source = std::string(source).c_str();
+  job.compilation_target = shader_compiler::TargetType::SpirV;
+  job.source_type = to_source_type(stage);
+
+  shader_compiler::Result *result = compiler->compile(job);
+
+  if (!result) {
+    return std::make_unique<std::vector<uint32_t>>();
+  }
+
+  /* Log compilation errors/warnings. */
+  if (!result->error_log.empty()) {
+    const char *error_log = result->error_log.c_str();
+    std::vector<char> error(error_log, error_log + result->error_log.size() + 1);
+    print_log(sources,
+              error.data(),
+              to_stage_name(stage).c_str(),
+              result->status_code == shader_compiler::StatusCode::CompilationError);
+    BLI_assert(!"Failed to compile shader!");
+  }
+
+  /* Retrieve compiled code. */
+  std::unique_ptr<std::vector<uint32_t>> bin = std::make_unique<std::vector<uint32_t>>();
+  switch (result->status_code) {
+    case shader_compiler::StatusCode::Ok:
+      bin = std::make_unique<std::vector<uint32_t>>(std::move(result->bin));
+      break;
+    case shader_compiler::StatusCode::CompilationError:
+      break;
+  }
+
+  delete result;
+  delete compiler;
+  return bin;
+}
+
+VkShaderModule VKShader::create_shader_module(MutableSpan<const char *> sources,
+                                              VKShaderStageType stage)
+{
+  std::unique_ptr<std::vector<uint32_t>> code = compile_source(sources, stage);
+  if (!code || code->size() == 0) {
+    compilation_failed_ = true;
+    return VK_NULL_HANDLE;
+  }
+
+  VkDevice device = context_->device_get();
+  VkShaderModuleCreateInfo shader_info = {};
+  shader_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+  shader_info.codeSize = code->size();
+  shader_info.pCode = reinterpret_cast<const uint32_t *>(code->data());
+
+  VkShaderModule shader_module;
+  if (vkCreateShaderModule(device, &shader_info, nullptr, &shader_module) != VK_SUCCESS) {
+    return VK_NULL_HANDLE;
+  }
+
+  return shader_module;
+}
+
+void VKShader::vertex_shader_from_glsl(MutableSpan<const char *> sources)
+{
+#ifdef VULKAN_SHADER_COMPILATION
+  vertex_shader_ = this->create_shader_module(sources, VKShaderStageType::VertexShader);
+#endif
+}
+
+void VKShader::geometry_shader_from_glsl(MutableSpan<const char *> sources)
+{
+#ifdef VULKAN_SHADER_COMPILATION
+  geometry_shader_ = this->create_shader_module(sources, VKShaderStageType::GeometryShader);
+#endif
+}
+
+void VKShader::fragment_shader_from_glsl(MutableSpan<const char *> sources)
+{
+#ifdef VULKAN_SHADER_COMPILATION
+  fragment_shader_ = this->create_shader_module(sources, VKShaderStageType::FragmentShader);
+#endif
+}
+
+/* TODO: Need to merge with master first. */
+#if 0
+void VKShader::compute_shader_from_glsl(MutableSpan<const char *> sources)
+{
+#  ifdef VULKAN_SHADER_COMPILATION
+  compute_shader_ = this->create_shader_module(sources, VKShaderStageType::Compute);
+#  endif
+}
+#endif
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Linking
+ * \{ */
+
+bool VKShader::finalize(void)
+{
+#ifdef VULKAN_SHADER_COMPILATION
+  if (compilation_failed_) {
+    return false;
+  }
+#endif
+
+  return true;
+};
+
+/** \} */
+
+}  // namespace blender::gpu
diff --git a/source/blender/gpu/vulkan/vk_shader.hh b/source/blender/gpu/vulkan/vk_shader.hh
index ff289c3067e..584a89ce3ef 100644
--- a/source/blender/gpu/vulkan/vk_shader.hh
+++ b/source/blender/gpu/vulkan/vk_shader.hh
@@ -25,33 +25,50 @@
 
 #include "MEM_guardedalloc.h"
 
+#include <vulkan/vulkan.h>
+
 #include "gpu_shader_private.hh"
 
 /* TODO move this deps to the .cc file. */
+#include "vk_context.hh"
 #include "vk_shader_interface.hh"
 
 namespace blender {
 namespace gpu {
 
+enum class VKShaderStageType {
+  VertexShader,
+  GeometryShader,
+  FragmentShader,
+  ComputeShader,
+};
+
+std::ostream &operator<<(std::ostream &os, const VKShaderStageType &stage);
+
 /**
  * Implementation of shader compilation and uniforms handling using OpenGL.
  **/
 class VKShader : public Shader {
+ private:
+  VKContext *context_ = nullptr;
+
+  VkShaderModule vertex_shader_ = VK_NULL_HANDLE;
+  VkShaderModule geometry_shader_ = VK_NULL_HANDLE;
+  VkShaderModule fragment_shader_ = VK_NULL_HANDLE;
+  VkShaderModule compute_shader_ = VK_NULL_HANDLE;
+
+  /** True if any shader failed to compile. */
+  bool compilation_failed_ = false;
+
  public:
-  VKShader(const char *name) : Shader(name)
-  {
-    interface = new VKShaderInterface();
-  };
-  ~VKShader(){};
+  VKShader(const char *name);
+  ~VKShader();
 
+  void vertex_shader_from_glsl(MutableSpan<const char *> sources) override;
+  void geometry_shader_from_glsl(MutableSpan<const

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list