1 // Copyright 2018 The Amber Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SRC_SHADER_COMPILER_H_
16 #define SRC_SHADER_COMPILER_H_
17 
18 #include <string>
19 #include <utility>
20 #include <vector>
21 
22 #include "amber/amber.h"
23 #include "amber/result.h"
24 #if AMBER_ENABLE_CLSPV
25 #include "spirv-tools/libspirv.h"
26 #endif
27 #include "src/pipeline.h"
28 #include "src/shader.h"
29 #include "src/virtual_file_store.h"
30 
31 namespace amber {
32 
33 /// Class to wrap the compilation of shaders.
34 class ShaderCompiler {
35  public:
36   ShaderCompiler();
37   ShaderCompiler(const std::string& env,
38                  bool disable_spirv_validation,
39                  VirtualFileStore* virtual_files);
40   ~ShaderCompiler();
41 
42   /// Returns a result code and a compilation of the given shader.
43   /// If the shader in |shader_info| has a corresponding entry in the
44   /// |shader_map|, then the compilation result is copied from that entry.
45   /// Otherwise a compiler is invoked to produce the compilation result.
46   ///
47   /// If |shader_info| specifies shader optimizations to run and there is no
48   /// entry in |shader_map| for that shader, then the SPIRV-Tools optimizer will
49   /// be invoked to produce the shader binary.
50   ///
51   /// |pipeline| is the pipeline containing |shader_info|. The name is used to
52   /// prefix shaders used in multiple pipelines with different optimization
53   /// flags. The pipeline is used in OPENCL-C compiles to create the literal
54   /// sampler bindings.
55   std::pair<Result, std::vector<uint32_t>> Compile(
56       Pipeline* pipeline,
57       Pipeline::ShaderInfo* shader_info,
58       const ShaderMap& shader_map) const;
59 
60  private:
61   Result ParseHex(const std::string& data, std::vector<uint32_t>* result) const;
62   Result CompileGlsl(const Shader* shader, std::vector<uint32_t>* result) const;
63   Result CompileHlsl(const Shader* shader,
64                      bool emit_debug_info,
65                      std::vector<uint32_t>* result) const;
66 #if AMBER_ENABLE_CLSPV
67   Result CompileOpenCLC(Pipeline::ShaderInfo* shader,
68                         Pipeline* pipeline,
69                         spv_target_env env,
70                         std::vector<uint32_t>* result) const;
71 #endif
72 
73   std::string spv_env_;
74   bool disable_spirv_validation_ = false;
75   VirtualFileStore* virtual_files_ = nullptr;
76 };
77 
78 // Parses the SPIR-V environment string, and returns the corresponding
79 // |target_env|, |target_env_version|, and |spirv_versoin|. Returns a failure
80 // value if the |spv_env| is invalid.
81 Result ParseSpvEnv(const std::string& spv_env,
82                    uint32_t* target_env,
83                    uint32_t* target_env_version,
84                    uint32_t* spirv_version);
85 
86 }  // namespace amber
87 
88 #endif  // SRC_SHADER_COMPILER_H_
89