[Bf-blender-cvs] [193a17474e6] tmp-vulkan: Added shader compiler abstration.

Jeroen Bakker noreply at git.blender.org
Wed Jun 23 14:10:13 CEST 2021


Commit: 193a17474e66c95b6095904aa81c5ab0a6c77748
Author: Jeroen Bakker
Date:   Wed Jun 23 14:04:44 2021 +0200
Branches: tmp-vulkan
https://developer.blender.org/rB193a17474e66c95b6095904aa81c5ab0a6c77748

Added shader compiler abstration.

The shader_compiler is an abstration layer for in case we need to switch
between other shader compilers in the future.

The shader compiler uses a CPP Api as it will only be accessed from GPU
module.

```
  const char *source = "#version 450\nvoid main() {}";
  shader_compiler::Compiler *compiler = shader_compiler::Compiler::create_default();
  shader_compiler::Job job;
  job.source = source;
  job.name = __func__;
  job.source_type = shader_compiler::SourceType::GlslComputeShader;
  job.compilation_target = shader_compiler::TargetType::SpirV;

  shader_compiler::Result *result = compiler->compile(job);
  EXPECT_EQ(result->type, shader_compiler::TargetType::SpirV);
  EXPECT_EQ(result->status_code, shader_compiler::StatusCode::Ok);
  EXPECT_GT(result->bin.size(), 0);
  EXPECT_EQ(result->error_log, "");
  delete result;
  delete compiler;
```

The CMakeFiles need some attention as it currently works when linking to
the shaderlib_combined. On linux it picks up the shaderlib from the
vulkan SDK, eventually it needs to pick up from our prebuild libraries.

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

A	build_files/cmake/Modules/FindShaderC.cmake
M	intern/CMakeLists.txt
A	intern/shader_compiler/CMakeLists.txt
A	intern/shader_compiler/intern/Compiler.cc
A	intern/shader_compiler/intern/Result.cc
A	intern/shader_compiler/intern/shaderc/ShaderCCompiler.cc
A	intern/shader_compiler/intern/shaderc/ShaderCCompiler.hh
A	intern/shader_compiler/intern/shaderc/ShaderCResult.cc
A	intern/shader_compiler/intern/shaderc/ShaderCResult.hh
A	intern/shader_compiler/shader_compiler.hh
M	source/blender/gpu/CMakeLists.txt
A	source/blender/gpu/tests/gpu_shader_compiler_test.cc

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

diff --git a/build_files/cmake/Modules/FindShaderC.cmake b/build_files/cmake/Modules/FindShaderC.cmake
new file mode 100644
index 00000000000..8e0ae550f14
--- /dev/null
+++ b/build_files/cmake/Modules/FindShaderC.cmake
@@ -0,0 +1,66 @@
+# - Find SHADERC library
+# Find the native Haru includes and library
+# This module defines
+#  SHADERC_INCLUDE_DIRS, where to find hpdf.h, set when
+#                        SHADERC_INCLUDE_DIR is found.
+#  SHADERC_LIBRARIES, libraries to link against to use Haru.
+#  SHADERC_ROOT_DIR, The base directory to search for Haru.
+#                    This can also be an environment variable.
+#  SHADERC_FOUND, If false, do not try to use Haru.
+#
+# also defined, but not for general use are
+#  SHADERC_LIBRARY, where to find the Haru library.
+
+#=============================================================================
+# Copyright 2021 Blender Foundation.
+#
+# Distributed under the OSI-approved BSD 3-Clause License,
+# see accompanying file BSD-3-Clause-license.txt for details.
+#=============================================================================
+
+# If SHADERC_ROOT_DIR was defined in the environment, use it.
+if(NOT SHADERC_ROOT_DIR AND NOT $ENV{SHADERC_ROOT_DIR} STREQUAL "")
+  set(SHADERC_ROOT_DIR $ENV{SHADERC_ROOT_DIR})
+endif()
+
+set(_shaderc_SEARCH_DIRS
+  ${SHADERC_ROOT_DIR}
+  /opt/lib/haru
+)
+
+find_path(SHADERC_INCLUDE_DIR
+  NAMES
+    shaderc.hpp
+  HINTS
+    ${_shaderc_SEARCH_DIRS}
+  PATH_SUFFIXES
+    include/shaderc
+    include
+)
+
+find_library(SHADERC_LIBRARY
+  NAMES
+    shaderc_combined
+    shaderc
+  HINTS
+    ${_shaderc_SEARCH_DIRS}
+  PATH_SUFFIXES
+    lib64 lib
+)
+
+# Handle the QUIETLY and REQUIRED arguments and set SHADERC_FOUND to TRUE if
+# all listed variables are TRUE.
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(ShaderC DEFAULT_MSG SHADERC_LIBRARY SHADERC_INCLUDE_DIR)
+
+if(SHADERC_FOUND)
+  set(SHADERC_LIBRARIES ${SHADERC_LIBRARY})
+  set(SHADERC_INCLUDE_DIRS ${SHADERC_INCLUDE_DIR})
+endif()
+
+mark_as_advanced(
+  SHADERC_INCLUDE_DIR
+  SHADERC_LIBRARY
+)
+
+unset(_shaderc_SEARCH_DIRS)
diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt
index dbd939e64b7..a7d30fe40b7 100644
--- a/intern/CMakeLists.txt
+++ b/intern/CMakeLists.txt
@@ -85,3 +85,7 @@ endif()
 if(UNIX AND NOT APPLE)
   add_subdirectory(libc_compat)
 endif()
+
+if(WITH_VULKAN)
+  add_subdirectory(shader_compiler)
+endif()
diff --git a/intern/shader_compiler/CMakeLists.txt b/intern/shader_compiler/CMakeLists.txt
new file mode 100644
index 00000000000..e9b88295148
--- /dev/null
+++ b/intern/shader_compiler/CMakeLists.txt
@@ -0,0 +1,47 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# 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) 2012, Blender Foundation
+# All rights reserved.
+# ***** END GPL LICENSE BLOCK *****
+
+set(INC
+  .
+  ../guardedalloc
+)
+
+find_package(ShaderC REQUIRED)
+
+
+set(INC_SYS
+    ${SHADERC_INCLUDE_DIRS}
+)
+
+set(SRC
+    intern/Compiler.cc
+    intern/Result.cc
+
+    intern/shaderc/ShaderCCompiler.cc
+    intern/shaderc/ShaderCResult.cc
+
+    shader_compiler.hh
+)
+
+set(LIB
+    ${SHADERC_LIBRARIES}
+)
+
+blender_add_lib(bf_intern_shadercompiler "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/intern/shader_compiler/intern/Compiler.cc b/intern/shader_compiler/intern/Compiler.cc
new file mode 100644
index 00000000000..ae606d95598
--- /dev/null
+++ b/intern/shader_compiler/intern/Compiler.cc
@@ -0,0 +1,13 @@
+#include "shader_compiler.hh"
+
+#include "intern/shaderc/ShaderCCompiler.hh"
+
+namespace shader_compiler {
+
+Compiler *Compiler::create_default()
+{
+  Compiler *compiler = new shaderc::ShaderCCompiler();
+  return compiler;
+}
+
+}  // namespace shader_compiler
diff --git a/intern/shader_compiler/intern/Result.cc b/intern/shader_compiler/intern/Result.cc
new file mode 100644
index 00000000000..34a33387af3
--- /dev/null
+++ b/intern/shader_compiler/intern/Result.cc
@@ -0,0 +1,10 @@
+#include "shader_compiler.hh"
+
+namespace shader_compiler {
+
+void Result::init(const Job &job)
+{
+  type = job.compilation_target;
+}
+
+}  // namespace shader_compiler
diff --git a/intern/shader_compiler/intern/shaderc/ShaderCCompiler.cc b/intern/shader_compiler/intern/shaderc/ShaderCCompiler.cc
new file mode 100644
index 00000000000..c8dddbea3aa
--- /dev/null
+++ b/intern/shader_compiler/intern/shaderc/ShaderCCompiler.cc
@@ -0,0 +1,65 @@
+
+#include "ShaderCCompiler.hh"
+#include "ShaderCResult.hh"
+#include "shaderc/shaderc.hpp"
+
+namespace shader_compiler::shaderc {
+
+ShaderCCompiler::ShaderCCompiler()
+{
+}
+
+ShaderCCompiler::~ShaderCCompiler()
+{
+}
+
+void ShaderCCompiler::set_optimization_level(::shaderc::CompileOptions options,
+                                             const OptimizationLevel new_value)
+{
+  switch (new_value) {
+    case OptimizationLevel::NotOptimized:
+      options.SetOptimizationLevel(shaderc_optimization_level_zero);
+      break;
+    case OptimizationLevel::SizeOptimized:
+      options.SetOptimizationLevel(shaderc_optimization_level_size);
+      break;
+    case OptimizationLevel::SpeedOptimized:
+      options.SetOptimizationLevel(shaderc_optimization_level_performance);
+      break;
+  }
+}
+
+shaderc_shader_kind ShaderCCompiler::get_source_kind(SourceType source_type)
+{
+  switch (source_type) {
+    case SourceType::GlslVertexShader:
+      return shaderc_glsl_vertex_shader;
+
+    case SourceType::GlslGeometryShader:
+      return shaderc_glsl_geometry_shader;
+
+    case SourceType::GlslFragmentShader:
+      return shaderc_glsl_fragment_shader;
+
+    case SourceType::GlslComputeShader:
+      return shaderc_glsl_compute_shader;
+  }
+  return shaderc_glsl_vertex_shader;
+}
+
+Result *ShaderCCompiler::compile(const Job &job)
+{
+  ::shaderc::CompileOptions options;
+  set_optimization_level(options, job.optimization_level);
+
+  shaderc_shader_kind kind = get_source_kind(job.source_type);
+
+  ::shaderc::SpvCompilationResult shaderc_result = compiler_.CompileGlslToSpv(
+      job.source, kind, job.name, options);
+
+  ShaderCResult *result = new ShaderCResult();
+  result->init(job, shaderc_result);
+  return result;
+}
+
+}  // namespace shader_compiler::shaderc
\ No newline at end of file
diff --git a/intern/shader_compiler/intern/shaderc/ShaderCCompiler.hh b/intern/shader_compiler/intern/shaderc/ShaderCCompiler.hh
new file mode 100644
index 00000000000..e699c86a440
--- /dev/null
+++ b/intern/shader_compiler/intern/shaderc/ShaderCCompiler.hh
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "shader_compiler.hh"
+
+#include "shaderc/shaderc.hpp"
+
+namespace shader_compiler::shaderc {
+
+class ShaderCCompiler : public Compiler {
+ private:
+  ::shaderc::Compiler compiler_;
+
+ public:
+  ShaderCCompiler();
+  ~ShaderCCompiler() override;
+
+  Result *compile(const Job &job) override;
+
+ private:
+  static void set_optimization_level(::shaderc::CompileOptions options,
+                                     const OptimizationLevel new_value);
+  static shaderc_shader_kind get_source_kind(SourceType source_type);
+};
+
+}  // namespace shader_compiler::shaderc
diff --git a/intern/shader_compiler/intern/shaderc/ShaderCResult.cc b/intern/shader_compiler/intern/shaderc/ShaderCResult.cc
new file mode 100644
index 00000000000..f0849ddd055
--- /dev/null
+++ b/intern/shader_compiler/intern/shaderc/ShaderCResult.cc
@@ -0,0 +1,40 @@
+
+#include "ShaderCResult.hh"
+
+namespace shader_compiler::shaderc {
+
+void ShaderCResult::init(const Job &job, ::shaderc::SpvCompilationResult &shaderc_result)
+{
+  Result::init(job);
+  status_code = status_code_from(shaderc_result);
+
+  switch (status_code) {
+    case StatusCode::Ok:
+      bin = {shaderc_result.cbegin(), shaderc_result.cend()};
+      break;
+
+    case StatusCode::CompilationError:
+      error_log = shaderc_result.GetErrorMessage();
+      break;
+  }
+}
+
+StatusCode ShaderCResult::status_code_from(::shaderc::SpvCompilationResult &shaderc_result)
+{
+  if (shaderc_result.GetCompilationStatus() != shaderc_compilation_status_success) {
+    return StatusCode::CompilationError;
+  }
+  return StatusCode::Ok;
+}
+
+std::vector<uint32_t> ShaderCResult::bin_from(::shaderc::SpvCompilationResult &shaderc_result)
+{
+  return {shaderc_result.cbegin(), shaderc_result.cend()};
+}
+
+std::string ShaderCResult::error_log_from(::shaderc::SpvCompilationResult &shaderc_result)
+{
+  return shaderc_result.GetErrorMessage();
+}
+
+}  // namespace shader_compiler::shaderc
\ No newline at end of file
diff --git a/intern/shader_compiler/intern/shaderc/ShaderCResult.hh b/intern/shader_compiler/intern/shaderc/ShaderCResult.hh
new file mode 100644
index 00000000000..4a3417c7a62
--- /dev/null
+++ b/intern/shader_compiler/intern/shaderc/ShaderCResult.hh
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "shader_compiler.hh"
+
+#include "shaderc/shaderc.hpp"
+
+namespace shader_compiler::shaderc {
+
+class ShaderCResult : public Result {
+
+ public:
+  void init(const Job &job, ::shaderc::SpvCompilationResult &shaderc_result);
+
+ private:
+  StatusCode status_code_from(::shaderc::SpvCompilationResult &shaderc_result);
+  std::string error_log_from(::shaderc::SpvCompilationResult &shaderc_result);
+  std::vector<uint32_t> bin_from(::shaderc::SpvCompilationResult &shaderc_result);
+};
+
+}  // namespace shader_compiler::shaderc
diff --git a/intern/shader_compiler/shader_compiler.hh b/intern/shader_compiler/shader_compiler.hh
new file mode 100644
index 00000000000..c1dd314c225
--- /dev/n

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list