[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