// Copyright 2015 The Shaderc Authors. All rights reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314#ifndef GLSLC_FILE_COMPILER_H15#define GLSLC_FILE_COMPILER_H1617#include <string>1819#include "libshaderc_util/file_finder.h"20#include "libshaderc_util/string_piece.h"21#include "shaderc/shaderc.hpp"2223#include "dependency_info.h"2425namespace glslc {2627// Describes an input file to be compiled.28struct InputFileSpec {29std::string name;30shaderc_shader_kind stage;31shaderc_source_language language;32std::string entry_point_name;33};3435// Context for managing compilation of source GLSL files into destination36// SPIR-V files or preprocessed output.37class FileCompiler {38public:39enum class SpirvBinaryEmissionFormat {40Unspecified, // No binary output format specified, this is the only valid41// option when the compilation output is not in SPIR-V binary42// code form.43Binary, // Emits SPIR-V binary code directly.44Numbers, // Emits SPIR-V binary code as a list of hex numbers.45CInitList, // Emits SPIR-V binary code as a C-style initializer list46// of hex numbers.47WGSL, // Emits SPIR-V module converted to WGSL source text.48// Requires a build with Tint support.49};5051FileCompiler()52: output_type_(OutputType::SpirvBinary),53binary_emission_format_(SpirvBinaryEmissionFormat::Unspecified),54needs_linking_(true),55total_warnings_(0),56total_errors_(0) {}5758// Compiles a shader received as specified by input_file, returning true59// on success and false otherwise. If force_shader_stage is not60// shaderc_glsl_infer_source or any default shader stage then the given61// shader_stage will be used, otherwise it will be determined from the source62// or the file type.63//64// Places the compilation output into a new file whose name is derived from65// input_file according to the rules from glslc/README.asciidoc.66//67// If version/profile has been forced, the shader's version/profile is set to68// that value regardless of the #version directive in the source code.69//70// Any errors/warnings found in the shader source will be output to std::cerr71// and increment the counts reported by OutputMessages().72bool CompileShaderFile(const InputFileSpec& input_file);7374// Adds a directory to be searched when processing #include directives.75//76// Best practice: if you add an empty string before any other path, that will77// correctly resolve both absolute paths and paths relative to the current78// working directory.79void AddIncludeDirectory(const std::string& path);8081// Sets the output filename. A name of "-" indicates standard output.82void SetOutputFileName(const shaderc_util::string_piece& file) {83output_file_name_ = file;84}8586// Sets the format for SPIR-V binary compilation output.87void SetSpirvBinaryOutputFormat(SpirvBinaryEmissionFormat format) {88binary_emission_format_ = format;89}9091// Returns false if any options are incompatible. The num_files parameter92// represents the number of files that will be compiled.93bool ValidateOptions(size_t num_files);9495// Outputs to std::cerr the number of warnings and errors if there are any.96void OutputMessages();9798// Sets the flag to indicate individual compilation mode. In this mode, all99// files are compiled individually and written to separate output files100// instead of linked together. This method also disables linking and sets the101// output file extension to ".spv". Disassembly mode and preprocessing only102// mode override this mode and flags.103void SetIndividualCompilationFlag();104105// Sets the flag to indicate disassembly mode. In this mode, the compiler106// emits disassembled textual output, instead of outputting object files.107// This method also sets the output file extension to ".spvasm" and disables108// linking. This mode overrides individual compilation mode, and preprocessing109// only mode overrides this mode.110void SetDisassemblyFlag();111112// Sets the flag to indicate preprocessing only mode. In this mode, instead of113// outputting object files, the compiler emits the preprocessed source files.114// This method disables linking and sets the output file to stdout. This mode115// overrides disassembly mode and individual compilation mode.116void SetPreprocessingOnlyFlag();117118// Gets the reference of the compiler options which reflects the command-line119// arguments.120shaderc::CompileOptions& options() { return options_; }121122// Gets a pointer which points to the dependency info dumping hander. Creates123// such a handler if such one does not exist.124DependencyInfoDumpingHandler* GetDependencyDumpingHandler() {125if (!dependency_info_dumping_handler_) {126dependency_info_dumping_handler_.reset(127new DependencyInfoDumpingHandler());128}129return dependency_info_dumping_handler_.get();130}131132private:133enum class OutputType {134SpirvBinary, // A binary module, as defined by the SPIR-V specification.135SpirvAssemblyText, // Assembly syntax defined by the SPIRV-Tools project.136PreprocessedText, // Preprocessed source code.137};138139// Emits the compilation output from the given result to the given output140// file and returns true if the result represents a successful compilation141// step. Otherwise returns false, possibly emits messages to the standard142// error stream, and does not produce an output file. Accumulates error143// and warning counts for use by the OutputMessages() method.144template <typename CompilationResultType>145bool EmitCompiledResult(146const CompilationResultType& result, const std::string& input_file_name,147const std::string& output_file_name,148shaderc_util::string_piece error_file_name,149const std::unordered_set<std::string>& used_source_files);150151// Returns the final file name to be used for the output file.152//153// If an output file name is specified by the SetOutputFileName(), use that154// argument as the final output file name.155//156// If the user did not specify an output filename:157// If linking is not required, and the input filename has a158// standard stage extension (e.g. .vert) then returns the input filename159// without directory names but with the result extenstion (e.g. .spv or160// .spvasm) appended.161//162// If linking is not required, and the input file name does not have a163// standard stage extension, then also returns the directory-stripped input164// filename, but replaces its extension with the result extension. (If the165// resolved input filename does not have an extension, then appends the166// result extension.)167//168// If linking is required and output filename is not specified, returns169// "a.spv".170std::string GetOutputFileName(std::string input_filename);171172// Returns the candidate output file name deduced from input file name and173// user specified output file name. It is computed as follows:174//175// If the user did specify an output filename and the compiler is not in176// preprocessing-only mode, then returns that file name.177//178// If the user did not specify an output filename:179// If the input filename has a standard stage extension (e.g. .vert) then180// returns the input filename without directory names but with the result181// extenstion (e.g. .spv or .spvasm) appended.182//183// If the input file name does not have a standard stage extension, then also184// returns the directory-stripped input filename, but replaces its extension185// with the result extension. (If the resolved input filename does not have186// an extension, then appends the result extension.)187//188// When a resolved extension is not available because the compiler is in189// preprocessing-only mode or the compilation requires linking, use .spv as190// the extension.191std::string GetCandidateOutputFileName(std::string input_filename);192193// Returns true if the compiler's output is preprocessed text.194bool PreprocessingOnly() {195return output_type_ == OutputType::PreprocessedText;196}197198// Performs actual SPIR-V compilation on the contents of input files.199shaderc::Compiler compiler_;200201// Reflects the command-line arguments and goes into202// compiler_.CompileGlslToSpv().203shaderc::CompileOptions options_;204205// What kind of output will be produced?206OutputType output_type_;207208// The Flag to indicate to which format the output SPIR-V binary code should209// be emitted.210SpirvBinaryEmissionFormat binary_emission_format_;211212// A FileFinder used to substitute #include directives in the source code.213shaderc_util::FileFinder include_file_finder_;214215// Indicates whether linking is needed to generate the final output.216bool needs_linking_;217218// The ownership of dependency dumping handler.219std::unique_ptr<DependencyInfoDumpingHandler>220dependency_info_dumping_handler_ = nullptr;221222// Reflects the type of file being generated.223std::string file_extension_;224// Name of the file where the compilation output will go.225shaderc_util::string_piece output_file_name_;226227// Counts warnings encountered in all compilations via this object.228size_t total_warnings_;229// Counts errors encountered in all compilations via this object.230size_t total_errors_;231};232} // namespace glslc233#endif // GLSLC_FILE_COMPILER_H234235236