First Commit
This commit is contained in:
104
3rdparty/shaderc/glslc/src/dependency_info.cc
vendored
Normal file
104
3rdparty/shaderc/glslc/src/dependency_info.cc
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
// Copyright 2015 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "dependency_info.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "file.h"
|
||||
#include "libshaderc_util/io_shaderc.h"
|
||||
|
||||
namespace glslc {
|
||||
|
||||
DependencyInfoDumpingHandler::DependencyInfoDumpingHandler() : mode_(not_set) {}
|
||||
|
||||
bool DependencyInfoDumpingHandler::DumpDependencyInfo(
|
||||
std::string compilation_output_file_name, std::string source_file_name,
|
||||
std::string* compilation_output_ptr,
|
||||
const std::unordered_set<std::string>& dependent_files) {
|
||||
std::string dep_target_label = GetTarget(compilation_output_file_name);
|
||||
std::string dep_file_name =
|
||||
GetDependencyFileName(compilation_output_file_name);
|
||||
|
||||
// Dump everything to a string stream first, then dump its content to either
|
||||
// a file or compilation output string, depends on current dumping mode.
|
||||
std::stringstream dep_string_stream;
|
||||
// dump target label and the source_file_name.
|
||||
dep_string_stream << dep_target_label << ": " << source_file_name;
|
||||
// dump the dependent file names.
|
||||
for (auto& dependent_file_name : dependent_files) {
|
||||
dep_string_stream << " " << dependent_file_name;
|
||||
}
|
||||
dep_string_stream << std::endl;
|
||||
|
||||
if (mode_ == dump_as_compilation_output) {
|
||||
compilation_output_ptr->assign(dep_string_stream.str());
|
||||
} else if (mode_ == dump_as_extra_file) {
|
||||
std::ofstream potential_file_stream_for_dep_info_dump;
|
||||
std::ostream* dep_file_stream = shaderc_util::GetOutputStream(
|
||||
dep_file_name, &potential_file_stream_for_dep_info_dump, &std::cerr);
|
||||
*dep_file_stream << dep_string_stream.str();
|
||||
if (dep_file_stream->fail()) {
|
||||
std::cerr << "glslc: error: error writing dependent_files info to output "
|
||||
"file: '"
|
||||
<< dep_file_name << "'" << std::endl;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// mode_ should not be 'not_set', we should never be here.
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string DependencyInfoDumpingHandler::GetTarget(
|
||||
const std::string& compilation_output_file_name) {
|
||||
if (!user_specified_dep_target_label_.empty()) {
|
||||
return user_specified_dep_target_label_;
|
||||
}
|
||||
|
||||
return compilation_output_file_name;
|
||||
}
|
||||
|
||||
std::string DependencyInfoDumpingHandler::GetDependencyFileName(
|
||||
const std::string& compilation_output_file_name) {
|
||||
if (!user_specified_dep_file_name_.empty()) {
|
||||
return user_specified_dep_file_name_;
|
||||
}
|
||||
|
||||
return compilation_output_file_name + ".d";
|
||||
}
|
||||
|
||||
bool DependencyInfoDumpingHandler::IsValid(std::string* error_msg_ptr,
|
||||
size_t num_files) {
|
||||
if (DumpingModeNotSet()) {
|
||||
*error_msg_ptr =
|
||||
"to generate dependencies you must specify either -M (-MM) or -MD";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!user_specified_dep_file_name_.empty() ||
|
||||
!user_specified_dep_target_label_.empty()) {
|
||||
if (num_files > 1) {
|
||||
*error_msg_ptr =
|
||||
"to specify dependency info file name or dependency info target, "
|
||||
"only one input file is allowed.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
136
3rdparty/shaderc/glslc/src/dependency_info.h
vendored
Normal file
136
3rdparty/shaderc/glslc/src/dependency_info.h
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
// Copyright 2015 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef GLSLC_DEPENDENCY_INFO_H
|
||||
#define GLSLC_DEPENDENCY_INFO_H
|
||||
|
||||
#include <unordered_set>
|
||||
#include <string>
|
||||
#include <string>
|
||||
|
||||
namespace glslc {
|
||||
|
||||
// An object to handle everything about dumping dependency info. Internally it
|
||||
// has two valid dumping mode: 1) Dump to extra dependency info files, such as
|
||||
// *.d files. This mode is used when we want to generate dependency info and
|
||||
// also compile. 2) Overwrite the original compilation output and dump
|
||||
// dependency info as compilation output. This mode is used when we do not want
|
||||
// to compile the source code and want the dependency info only.
|
||||
class DependencyInfoDumpingHandler {
|
||||
public:
|
||||
DependencyInfoDumpingHandler();
|
||||
|
||||
// Sets the dependency target explicitly. It's the same as the argument to
|
||||
// -MT.
|
||||
void SetTarget(const std::string& target_label) {
|
||||
user_specified_dep_target_label_ = target_label;
|
||||
}
|
||||
|
||||
// Sets the name of the file where dependency info will be written.
|
||||
void SetDependencyFileName(const std::string& dep_file_name) {
|
||||
user_specified_dep_file_name_ = dep_file_name;
|
||||
}
|
||||
|
||||
// Dump depdendency info to a) an extra dependency info file, b) an string
|
||||
// which holds the compilation output. The choice depends on the dump
|
||||
// mode of the handler. Returns true if dumping is succeeded, false otherwise.
|
||||
//
|
||||
// The dependency file name and target are deduced based on 1) user
|
||||
// specified dependency file name and target name, 2) the output filename when
|
||||
// the compiler is in 'does not need linking' and 'not preprocessing-only'
|
||||
// mode. It is passed through compilation_output_file_name.
|
||||
//
|
||||
// When the handler is set to dump dependency info as extra dependency info
|
||||
// files, this method will open a file with the dependency file name and write
|
||||
// the dependency info to it. Error messages caused by writing to the file are
|
||||
// emitted to stderr.
|
||||
//
|
||||
// When the handler is set to dump dependency info as compilation output, the
|
||||
// compilation output string, which is passed through compilation_output_ptr,
|
||||
// will be cleared and this method will write dependency info to it. Then the
|
||||
// dependency info should be emitted as normal compilation output.
|
||||
//
|
||||
// If the dump mode is not set when this method is called, return false.
|
||||
bool DumpDependencyInfo(std::string compilation_output_file_name,
|
||||
std::string source_file_name,
|
||||
std::string* compilation_output_ptr,
|
||||
const std::unordered_set<std::string>& dependent_files);
|
||||
|
||||
// Sets to always dump dependency info as an extra file, instead of the normal
|
||||
// compilation output. This means the output name specified by -o options
|
||||
// won't be used for the dependency info file.
|
||||
void SetDumpToExtraDependencyInfoFiles() { mode_ = dump_as_extra_file; }
|
||||
|
||||
// Sets to dump dependency info as normal compilation output. The dependency
|
||||
// info will be either saved in a file with -o option specified file, or, if
|
||||
// no output file name specified, to stdout.
|
||||
void SetDumpAsNormalCompilationOutput() {
|
||||
mode_ = dump_as_compilation_output;
|
||||
}
|
||||
|
||||
// Returns true if the handler's dumping mode is set to dump dependency info
|
||||
// as extra dependency info files.
|
||||
bool DumpingToExtraDependencyInfoFiles() {
|
||||
return mode_ == dump_as_extra_file;
|
||||
}
|
||||
|
||||
// Returns true if the handler's dumping mode is set to dump dependency info
|
||||
// as normal compilation output.
|
||||
bool DumpingAsCompilationOutput() {
|
||||
return mode_ == dump_as_compilation_output;
|
||||
}
|
||||
|
||||
// Returns true if the handler's dumping mode is not set.
|
||||
bool DumpingModeNotSet() { return mode_ == not_set; }
|
||||
|
||||
// Returns true if the handler is at valid state for dumping dependency info.
|
||||
bool IsValid(std::string* error_msg_ptr, size_t num_files);
|
||||
|
||||
private:
|
||||
typedef enum {
|
||||
// not_set mode tells that the dumping mode is not set yet, so the handler
|
||||
// is not ready for dumping dependency info. Calling DumpDependencyInfo when
|
||||
// the handler is in this mode will cause failure.
|
||||
not_set = 0,
|
||||
// Dumping dependency info as normal compilation output mode. In this mode,
|
||||
// the dependency info will be dumped as compilation output by overwriting
|
||||
// the string which holds the compilation output.
|
||||
dump_as_compilation_output,
|
||||
// Dumping dependency info as extra dependency info files mode. In this
|
||||
// mode, dependency info will be dumped to a user specified dependency info
|
||||
// file or a *.d file. Compilation output will still be generated along with
|
||||
// the dependency info.
|
||||
dump_as_extra_file,
|
||||
} dump_mode;
|
||||
|
||||
// Returns the target file label to be used in depdendency info file. If -MT
|
||||
// defined a label, use that string as the label. Otherwise returns the
|
||||
// compilation output filename deduced in 'doesn't need linking' and 'not
|
||||
// preprocessing-only' mode.
|
||||
std::string GetTarget(const std::string& compilation_output_file_name);
|
||||
|
||||
// Returns the dependency file name to be used. If -MF defined a file name
|
||||
// before, use it. Othwise, returns a filename formed by appending .d to the
|
||||
// output filename deduced in 'doesn't need linking' and 'no
|
||||
// preprocessing-only' mode.
|
||||
std::string GetDependencyFileName(
|
||||
const std::string& compilation_output_file_name);
|
||||
|
||||
std::string user_specified_dep_file_name_;
|
||||
std::string user_specified_dep_target_label_;
|
||||
dump_mode mode_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // GLSLC_DEPENDENCY_INFO_H
|
||||
26
3rdparty/shaderc/glslc/src/file.cc
vendored
Normal file
26
3rdparty/shaderc/glslc/src/file.cc
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2015 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "file.h"
|
||||
|
||||
namespace glslc {
|
||||
|
||||
shaderc_util::string_piece GetFileExtension(
|
||||
const shaderc_util::string_piece& filename) {
|
||||
size_t dot_pos = filename.find_last_of(".");
|
||||
if (dot_pos == shaderc_util::string_piece::npos) return "";
|
||||
return filename.substr(dot_pos + 1);
|
||||
}
|
||||
|
||||
} // namespace glslc
|
||||
46
3rdparty/shaderc/glslc/src/file.h
vendored
Normal file
46
3rdparty/shaderc/glslc/src/file.h
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright 2015 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef GLSLC_FILE_H_
|
||||
#define GLSLC_FILE_H_
|
||||
|
||||
#include "libshaderc_util/string_piece.h"
|
||||
|
||||
namespace glslc {
|
||||
|
||||
// Given a file name, returns its extension. If no extension exists,
|
||||
// returns an empty string_piece.
|
||||
shaderc_util::string_piece GetFileExtension(
|
||||
const shaderc_util::string_piece& filename);
|
||||
|
||||
// Returns true if the given file name ends with a known shader file extension.
|
||||
inline bool IsStageFile(const shaderc_util::string_piece& filename) {
|
||||
const shaderc_util::string_piece extension =
|
||||
glslc::GetFileExtension(filename);
|
||||
return extension == "vert" || extension == "frag" || extension == "tesc" ||
|
||||
extension == "tese" || extension == "geom" || extension == "comp";
|
||||
}
|
||||
|
||||
// Returns the file extension if is either "glsl" or "hlsl", or an empty
|
||||
// string otherwise.
|
||||
inline std::string GetGlslOrHlslExtension(
|
||||
const shaderc_util::string_piece& filename) {
|
||||
auto extension = glslc::GetFileExtension(filename);
|
||||
if ((extension == "glsl") || (extension == "hlsl")) return extension.str();
|
||||
return "";
|
||||
}
|
||||
|
||||
} // namespace glslc
|
||||
|
||||
#endif // GLSLC_FILE_H_
|
||||
435
3rdparty/shaderc/glslc/src/file_compiler.cc
vendored
Normal file
435
3rdparty/shaderc/glslc/src/file_compiler.cc
vendored
Normal file
@@ -0,0 +1,435 @@
|
||||
// Copyright 2015 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "file_compiler.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#if SHADERC_ENABLE_WGSL_OUTPUT == 1
|
||||
#include "tint/tint.h"
|
||||
#endif // SHADERC_ENABLE_WGSL_OUTPUT==1
|
||||
|
||||
#include "file.h"
|
||||
#include "file_includer.h"
|
||||
#include "shader_stage.h"
|
||||
|
||||
#include "libshaderc_util/io_shaderc.h"
|
||||
#include "libshaderc_util/message.h"
|
||||
|
||||
namespace {
|
||||
using shaderc_util::string_piece;
|
||||
|
||||
// A helper function to emit SPIR-V binary code as a list of hex numbers in
|
||||
// text form. Returns true if a non-empty compilation result is emitted
|
||||
// successfully. Return false if nothing should be emitted, either because the
|
||||
// compilation result is empty, or the compilation output is not SPIR-V binary
|
||||
// code.
|
||||
template <typename CompilationResultType>
|
||||
bool EmitSpirvBinaryAsCommaSeparatedNumbers(const CompilationResultType& result,
|
||||
std::ostream* out) {
|
||||
// Return early if the compilation output is not in SPIR-V binary code form.
|
||||
if (!std::is_same<CompilationResultType,
|
||||
shaderc::SpvCompilationResult>::value)
|
||||
return false;
|
||||
// Return early if the compilation result is empty.
|
||||
if (result.cbegin() == result.cend()) return false;
|
||||
std::ios::fmtflags output_stream_flag_cache(out->flags());
|
||||
*out << std::hex << std::setfill('0');
|
||||
auto RI = result.cbegin();
|
||||
*out << "0x" << std::setw(8) << *RI++;
|
||||
for (size_t counter = 1; RI != result.cend(); RI++, counter++) {
|
||||
*out << ",";
|
||||
// Break line for every four words.
|
||||
if (counter % 4 == 0) {
|
||||
*out << std::endl;
|
||||
}
|
||||
*out << "0x" << std::setw(8) << *RI;
|
||||
}
|
||||
out->flags(output_stream_flag_cache);
|
||||
return true;
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
namespace glslc {
|
||||
bool FileCompiler::CompileShaderFile(const InputFileSpec& input_file) {
|
||||
std::vector<char> input_data;
|
||||
std::string path = input_file.name;
|
||||
if (!shaderc_util::ReadFile(path, &input_data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string output_file_name = GetOutputFileName(input_file.name);
|
||||
string_piece error_file_name = input_file.name;
|
||||
|
||||
if (error_file_name == "-") {
|
||||
// If the input file was stdin, we want to output errors as <stdin>.
|
||||
error_file_name = "<stdin>";
|
||||
}
|
||||
|
||||
string_piece source_string = "";
|
||||
if (!input_data.empty()) {
|
||||
source_string = {&input_data.front(),
|
||||
&input_data.front() + input_data.size()};
|
||||
}
|
||||
|
||||
std::unique_ptr<FileIncluder> includer(
|
||||
new FileIncluder(&include_file_finder_));
|
||||
// Get a reference to the dependency trace before we pass the ownership to
|
||||
// shaderc::CompileOptions.
|
||||
const auto& used_source_files = includer->file_path_trace();
|
||||
options_.SetIncluder(std::move(includer));
|
||||
|
||||
if (input_file.stage == shaderc_spirv_assembly) {
|
||||
// Only act if the requested target is SPIR-V binary.
|
||||
if (output_type_ == OutputType::SpirvBinary) {
|
||||
const auto result =
|
||||
compiler_.AssembleToSpv(source_string.data(), source_string.size());
|
||||
return EmitCompiledResult(result, input_file.name, output_file_name,
|
||||
error_file_name, used_source_files);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the language. Since we only use the options object in this
|
||||
// method, then it's ok to always set it without resetting it after
|
||||
// compilation. A subsequent compilation will set it again anyway.
|
||||
options_.SetSourceLanguage(input_file.language);
|
||||
|
||||
switch (output_type_) {
|
||||
case OutputType::SpirvBinary: {
|
||||
const auto result = compiler_.CompileGlslToSpv(
|
||||
source_string.data(), source_string.size(), input_file.stage,
|
||||
error_file_name.data(), input_file.entry_point_name.c_str(),
|
||||
options_);
|
||||
return EmitCompiledResult(result, input_file.name, output_file_name,
|
||||
error_file_name, used_source_files);
|
||||
}
|
||||
case OutputType::SpirvAssemblyText: {
|
||||
const auto result = compiler_.CompileGlslToSpvAssembly(
|
||||
source_string.data(), source_string.size(), input_file.stage,
|
||||
error_file_name.data(), input_file.entry_point_name.c_str(),
|
||||
options_);
|
||||
return EmitCompiledResult(result, input_file.name, output_file_name,
|
||||
error_file_name, used_source_files);
|
||||
}
|
||||
case OutputType::PreprocessedText: {
|
||||
const auto result = compiler_.PreprocessGlsl(
|
||||
source_string.data(), source_string.size(), input_file.stage,
|
||||
error_file_name.data(), options_);
|
||||
return EmitCompiledResult(result, input_file.name, output_file_name,
|
||||
error_file_name, used_source_files);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename CompilationResultType>
|
||||
bool FileCompiler::EmitCompiledResult(
|
||||
const CompilationResultType& result, const std::string& input_file,
|
||||
const std::string& output_file_name, string_piece error_file_name,
|
||||
const std::unordered_set<std::string>& used_source_files) {
|
||||
total_errors_ += result.GetNumErrors();
|
||||
total_warnings_ += result.GetNumWarnings();
|
||||
|
||||
bool compilation_success =
|
||||
result.GetCompilationStatus() == shaderc_compilation_status_success;
|
||||
|
||||
// Handle the error message for failing to deduce the shader kind.
|
||||
if (result.GetCompilationStatus() ==
|
||||
shaderc_compilation_status_invalid_stage) {
|
||||
auto glsl_or_hlsl_extension = GetGlslOrHlslExtension(error_file_name);
|
||||
if (glsl_or_hlsl_extension != "") {
|
||||
std::cerr << "glslc: error: "
|
||||
<< "'" << error_file_name << "': "
|
||||
<< "." << glsl_or_hlsl_extension
|
||||
<< " file encountered but no -fshader-stage specified ahead";
|
||||
} else if (error_file_name == "<stdin>") {
|
||||
std::cerr
|
||||
<< "glslc: error: '-': -fshader-stage required when input is from "
|
||||
"standard "
|
||||
"input \"-\"";
|
||||
} else {
|
||||
std::cerr << "glslc: error: "
|
||||
<< "'" << error_file_name << "': "
|
||||
<< "file not recognized: File format not recognized";
|
||||
}
|
||||
std::cerr << "\n";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get a string_piece which refers to the normal compilation output for now.
|
||||
// This string_piece might be redirected to the dependency info to be dumped
|
||||
// later, if the handler is instantiated to dump as normal compilation output,
|
||||
// and the original compilation output should be blocked. Otherwise it won't
|
||||
// be touched. The main output stream dumps this string_piece later.
|
||||
string_piece compilation_output(
|
||||
reinterpret_cast<const char*>(result.cbegin()),
|
||||
reinterpret_cast<const char*>(result.cend()));
|
||||
|
||||
// If we have dependency info dumping handler instantiated, we should dump
|
||||
// dependency info first. This may redirect the compilation output
|
||||
// string_piece to dependency info.
|
||||
std::string potential_dependency_info_output;
|
||||
if (dependency_info_dumping_handler_) {
|
||||
if (!dependency_info_dumping_handler_->DumpDependencyInfo(
|
||||
GetCandidateOutputFileName(input_file), error_file_name.data(),
|
||||
&potential_dependency_info_output, used_source_files)) {
|
||||
return false;
|
||||
}
|
||||
if (!potential_dependency_info_output.empty()) {
|
||||
// If the potential_dependency_info_output string is not empty, it means
|
||||
// we should dump dependency info as normal compilation output. Redirect
|
||||
// the compilation output string_piece to the dependency info stored in
|
||||
// potential_dependency_info_output to make it happen.
|
||||
compilation_output = potential_dependency_info_output;
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream* out = nullptr;
|
||||
std::ofstream potential_file_stream;
|
||||
if (compilation_success) {
|
||||
out = shaderc_util::GetOutputStream(output_file_name,
|
||||
&potential_file_stream, &std::cerr);
|
||||
if (!out || out->fail()) {
|
||||
// An error message has already been emitted to the stderr stream.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write compilation output to output file. If an output format for SPIR-V
|
||||
// binary code is specified, it is handled here.
|
||||
switch (binary_emission_format_) {
|
||||
case SpirvBinaryEmissionFormat::Unspecified:
|
||||
case SpirvBinaryEmissionFormat::Binary:
|
||||
// The output format is unspecified or specified as binary output.
|
||||
// On Windows, the output stream must be set to binary mode. By
|
||||
// default the standard output stream is set to text mode, which
|
||||
// translates newlines (\n) to carriage-return newline pairs
|
||||
// (\r\n).
|
||||
if (out == &std::cout) shaderc_util::FlushAndSetBinaryModeOnStdout();
|
||||
out->write(compilation_output.data(), compilation_output.size());
|
||||
if (out == &std::cout) shaderc_util::FlushAndSetTextModeOnStdout();
|
||||
break;
|
||||
case SpirvBinaryEmissionFormat::Numbers:
|
||||
// The output format is specified to be a list of hex numbers, the
|
||||
// compilation output must be in SPIR-V binary code form.
|
||||
assert(output_type_ == OutputType::SpirvBinary);
|
||||
if (EmitSpirvBinaryAsCommaSeparatedNumbers(result, out)) {
|
||||
// Only emits the end-of-line character when the emitted compilation
|
||||
// result is not empty.
|
||||
*out << std::endl;
|
||||
}
|
||||
break;
|
||||
case SpirvBinaryEmissionFormat::CInitList:
|
||||
// The output format is specified to be a C-style initializer list, the
|
||||
// compilation output must be in SPIR-V binary code form.
|
||||
assert(output_type_ == OutputType::SpirvBinary);
|
||||
if (result.begin() != result.end()) {
|
||||
// Only emits the '{' when the compilation result is not empty.
|
||||
*out << "{";
|
||||
}
|
||||
if (EmitSpirvBinaryAsCommaSeparatedNumbers(result, out)) {
|
||||
// Only emits the end-of-line character when the emitted compilation
|
||||
// result is not empty.
|
||||
*out << "}" << std::endl;
|
||||
}
|
||||
break;
|
||||
case SpirvBinaryEmissionFormat::WGSL: {
|
||||
#if SHADERC_ENABLE_WGSL_OUTPUT == 1
|
||||
tint::Context ctx;
|
||||
tint::reader::spirv::Parser spv_reader(
|
||||
&ctx, std::vector<uint32_t>(result.begin(), result.end()));
|
||||
if (!spv_reader.Parse()) {
|
||||
std::cout << "error: failed to convert SPIR-V binary to WGSL: "
|
||||
<< spv_reader.error() << std::endl;
|
||||
return false;
|
||||
}
|
||||
tint::writer::wgsl::Generator wgsl_writer(spv_reader.module());
|
||||
if (!wgsl_writer.Generate()) {
|
||||
std::cout << "error: failed to convert to WGSL: "
|
||||
<< wgsl_writer.error() << std::endl;
|
||||
return false;
|
||||
}
|
||||
*out << wgsl_writer.result();
|
||||
#endif // SHADERC_ENABLE_WGSL_OUTPUT==1
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write error message to std::cerr.
|
||||
std::cerr << result.GetErrorMessage();
|
||||
if (out && out->fail()) {
|
||||
// Something wrong happened on output.
|
||||
if (out == &std::cout) {
|
||||
std::cerr << "glslc: error: error writing to standard output"
|
||||
<< std::endl;
|
||||
} else {
|
||||
std::cerr << "glslc: error: error writing to output file: '"
|
||||
<< output_file_name_ << "'" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return compilation_success;
|
||||
}
|
||||
|
||||
void FileCompiler::AddIncludeDirectory(const std::string& path) {
|
||||
include_file_finder_.search_path().push_back(path);
|
||||
}
|
||||
|
||||
void FileCompiler::SetIndividualCompilationFlag() {
|
||||
if (output_type_ != OutputType::SpirvAssemblyText) {
|
||||
needs_linking_ = false;
|
||||
file_extension_ = ".spv";
|
||||
}
|
||||
}
|
||||
|
||||
void FileCompiler::SetDisassemblyFlag() {
|
||||
if (!PreprocessingOnly()) {
|
||||
output_type_ = OutputType::SpirvAssemblyText;
|
||||
needs_linking_ = false;
|
||||
file_extension_ = ".spvasm";
|
||||
}
|
||||
}
|
||||
|
||||
void FileCompiler::SetPreprocessingOnlyFlag() {
|
||||
output_type_ = OutputType::PreprocessedText;
|
||||
needs_linking_ = false;
|
||||
if (output_file_name_.empty()) {
|
||||
output_file_name_ = "-";
|
||||
}
|
||||
}
|
||||
|
||||
bool FileCompiler::ValidateOptions(size_t num_files) {
|
||||
if (num_files == 0) {
|
||||
std::cerr << "glslc: error: no input files" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (num_files > 1 && needs_linking_) {
|
||||
std::cerr << "glslc: error: linking multiple files is not supported yet. "
|
||||
"Use -c to compile files individually."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we are outputting many object files, we cannot specify -o. Also
|
||||
// if we are preprocessing multiple files they must be to stdout.
|
||||
if (num_files > 1 && ((!PreprocessingOnly() && !needs_linking_ &&
|
||||
!output_file_name_.empty()) ||
|
||||
(PreprocessingOnly() && output_file_name_ != "-"))) {
|
||||
std::cerr << "glslc: error: cannot specify -o when generating multiple"
|
||||
" output files"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we have dependency info dumping handler instantiated, we should check
|
||||
// its validity.
|
||||
if (dependency_info_dumping_handler_) {
|
||||
std::string dependency_info_dumping_hander_error_msg;
|
||||
if (!dependency_info_dumping_handler_->IsValid(
|
||||
&dependency_info_dumping_hander_error_msg, num_files)) {
|
||||
std::cerr << "glslc: error: " << dependency_info_dumping_hander_error_msg
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If the output format is specified to be a binary, a list of hex numbers or
|
||||
// a C-style initializer list, the output must be in SPIR-V binary code form.
|
||||
if (binary_emission_format_ != SpirvBinaryEmissionFormat::Unspecified) {
|
||||
if (output_type_ != OutputType::SpirvBinary) {
|
||||
std::cerr << "glslc: error: cannot emit output as a ";
|
||||
switch (binary_emission_format_) {
|
||||
case SpirvBinaryEmissionFormat::Binary:
|
||||
std::cerr << "binary";
|
||||
break;
|
||||
case SpirvBinaryEmissionFormat::Numbers:
|
||||
std::cerr << "list of hex numbers";
|
||||
break;
|
||||
case SpirvBinaryEmissionFormat::CInitList:
|
||||
std::cerr << "C-style initializer list";
|
||||
break;
|
||||
case SpirvBinaryEmissionFormat::WGSL:
|
||||
std::cerr << "WGSL source program";
|
||||
break;
|
||||
case SpirvBinaryEmissionFormat::Unspecified:
|
||||
// The compiler should never be here at runtime. This case is added to
|
||||
// complete the switch cases.
|
||||
break;
|
||||
}
|
||||
std::cerr << " when only preprocessing the source" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (dependency_info_dumping_handler_ &&
|
||||
dependency_info_dumping_handler_->DumpingAsCompilationOutput()) {
|
||||
std::cerr << "glslc: error: cannot dump dependency info when specifying "
|
||||
"any binary output format"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (binary_emission_format_ == SpirvBinaryEmissionFormat::WGSL) {
|
||||
#if SHADERC_ENABLE_WGSL_OUTPUT != 1
|
||||
std::cerr << "glslc: error: can't output WGSL: glslc was built without "
|
||||
"WGSL output support"
|
||||
<< std::endl;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileCompiler::OutputMessages() {
|
||||
shaderc_util::OutputMessages(&std::cerr, total_warnings_, total_errors_);
|
||||
}
|
||||
|
||||
std::string FileCompiler::GetOutputFileName(std::string input_filename) {
|
||||
if (output_file_name_.empty()) {
|
||||
return needs_linking_ ? std::string("a.spv")
|
||||
: GetCandidateOutputFileName(input_filename);
|
||||
} else {
|
||||
return output_file_name_.str();
|
||||
}
|
||||
}
|
||||
|
||||
std::string FileCompiler::GetCandidateOutputFileName(
|
||||
std::string input_filename) {
|
||||
if (!output_file_name_.empty() && !PreprocessingOnly()) {
|
||||
return output_file_name_.str();
|
||||
}
|
||||
|
||||
std::string extension = file_extension_;
|
||||
if (PreprocessingOnly() || needs_linking_) {
|
||||
extension = ".spv";
|
||||
}
|
||||
|
||||
std::string candidate_output_file_name =
|
||||
IsStageFile(input_filename)
|
||||
? shaderc_util::GetBaseFileName(input_filename) + extension
|
||||
: shaderc_util::GetBaseFileName(
|
||||
input_filename.substr(0, input_filename.find_last_of('.')) +
|
||||
extension);
|
||||
return candidate_output_file_name;
|
||||
}
|
||||
} // namesapce glslc
|
||||
234
3rdparty/shaderc/glslc/src/file_compiler.h
vendored
Normal file
234
3rdparty/shaderc/glslc/src/file_compiler.h
vendored
Normal file
@@ -0,0 +1,234 @@
|
||||
// Copyright 2015 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef GLSLC_FILE_COMPILER_H
|
||||
#define GLSLC_FILE_COMPILER_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "libshaderc_util/file_finder.h"
|
||||
#include "libshaderc_util/string_piece.h"
|
||||
#include "shaderc/shaderc.hpp"
|
||||
|
||||
#include "dependency_info.h"
|
||||
|
||||
namespace glslc {
|
||||
|
||||
// Describes an input file to be compiled.
|
||||
struct InputFileSpec {
|
||||
std::string name;
|
||||
shaderc_shader_kind stage;
|
||||
shaderc_source_language language;
|
||||
std::string entry_point_name;
|
||||
};
|
||||
|
||||
// Context for managing compilation of source GLSL files into destination
|
||||
// SPIR-V files or preprocessed output.
|
||||
class FileCompiler {
|
||||
public:
|
||||
enum class SpirvBinaryEmissionFormat {
|
||||
Unspecified, // No binary output format specified, this is the only valid
|
||||
// option when the compilation output is not in SPIR-V binary
|
||||
// code form.
|
||||
Binary, // Emits SPIR-V binary code directly.
|
||||
Numbers, // Emits SPIR-V binary code as a list of hex numbers.
|
||||
CInitList, // Emits SPIR-V binary code as a C-style initializer list
|
||||
// of hex numbers.
|
||||
WGSL, // Emits SPIR-V module converted to WGSL source text.
|
||||
// Requires a build with Tint support.
|
||||
};
|
||||
|
||||
FileCompiler()
|
||||
: output_type_(OutputType::SpirvBinary),
|
||||
binary_emission_format_(SpirvBinaryEmissionFormat::Unspecified),
|
||||
needs_linking_(true),
|
||||
total_warnings_(0),
|
||||
total_errors_(0) {}
|
||||
|
||||
// Compiles a shader received as specified by input_file, returning true
|
||||
// on success and false otherwise. If force_shader_stage is not
|
||||
// shaderc_glsl_infer_source or any default shader stage then the given
|
||||
// shader_stage will be used, otherwise it will be determined from the source
|
||||
// or the file type.
|
||||
//
|
||||
// Places the compilation output into a new file whose name is derived from
|
||||
// input_file according to the rules from glslc/README.asciidoc.
|
||||
//
|
||||
// If version/profile has been forced, the shader's version/profile is set to
|
||||
// that value regardless of the #version directive in the source code.
|
||||
//
|
||||
// Any errors/warnings found in the shader source will be output to std::cerr
|
||||
// and increment the counts reported by OutputMessages().
|
||||
bool CompileShaderFile(const InputFileSpec& input_file);
|
||||
|
||||
// Adds a directory to be searched when processing #include directives.
|
||||
//
|
||||
// Best practice: if you add an empty string before any other path, that will
|
||||
// correctly resolve both absolute paths and paths relative to the current
|
||||
// working directory.
|
||||
void AddIncludeDirectory(const std::string& path);
|
||||
|
||||
// Sets the output filename. A name of "-" indicates standard output.
|
||||
void SetOutputFileName(const shaderc_util::string_piece& file) {
|
||||
output_file_name_ = file;
|
||||
}
|
||||
|
||||
// Sets the format for SPIR-V binary compilation output.
|
||||
void SetSpirvBinaryOutputFormat(SpirvBinaryEmissionFormat format) {
|
||||
binary_emission_format_ = format;
|
||||
}
|
||||
|
||||
// Returns false if any options are incompatible. The num_files parameter
|
||||
// represents the number of files that will be compiled.
|
||||
bool ValidateOptions(size_t num_files);
|
||||
|
||||
// Outputs to std::cerr the number of warnings and errors if there are any.
|
||||
void OutputMessages();
|
||||
|
||||
// Sets the flag to indicate individual compilation mode. In this mode, all
|
||||
// files are compiled individually and written to separate output files
|
||||
// instead of linked together. This method also disables linking and sets the
|
||||
// output file extension to ".spv". Disassembly mode and preprocessing only
|
||||
// mode override this mode and flags.
|
||||
void SetIndividualCompilationFlag();
|
||||
|
||||
// Sets the flag to indicate disassembly mode. In this mode, the compiler
|
||||
// emits disassembled textual output, instead of outputting object files.
|
||||
// This method also sets the output file extension to ".spvasm" and disables
|
||||
// linking. This mode overrides individual compilation mode, and preprocessing
|
||||
// only mode overrides this mode.
|
||||
void SetDisassemblyFlag();
|
||||
|
||||
// Sets the flag to indicate preprocessing only mode. In this mode, instead of
|
||||
// outputting object files, the compiler emits the preprocessed source files.
|
||||
// This method disables linking and sets the output file to stdout. This mode
|
||||
// overrides disassembly mode and individual compilation mode.
|
||||
void SetPreprocessingOnlyFlag();
|
||||
|
||||
// Gets the reference of the compiler options which reflects the command-line
|
||||
// arguments.
|
||||
shaderc::CompileOptions& options() { return options_; }
|
||||
|
||||
// Gets a pointer which points to the dependency info dumping hander. Creates
|
||||
// such a handler if such one does not exist.
|
||||
DependencyInfoDumpingHandler* GetDependencyDumpingHandler() {
|
||||
if (!dependency_info_dumping_handler_) {
|
||||
dependency_info_dumping_handler_.reset(
|
||||
new DependencyInfoDumpingHandler());
|
||||
}
|
||||
return dependency_info_dumping_handler_.get();
|
||||
}
|
||||
|
||||
private:
|
||||
enum class OutputType {
|
||||
SpirvBinary, // A binary module, as defined by the SPIR-V specification.
|
||||
SpirvAssemblyText, // Assembly syntax defined by the SPIRV-Tools project.
|
||||
PreprocessedText, // Preprocessed source code.
|
||||
};
|
||||
|
||||
// Emits the compilation output from the given result to the given output
|
||||
// file and returns true if the result represents a successful compilation
|
||||
// step. Otherwise returns false, possibly emits messages to the standard
|
||||
// error stream, and does not produce an output file. Accumulates error
|
||||
// and warning counts for use by the OutputMessages() method.
|
||||
template <typename CompilationResultType>
|
||||
bool EmitCompiledResult(
|
||||
const CompilationResultType& result, const std::string& input_file_name,
|
||||
const std::string& output_file_name,
|
||||
shaderc_util::string_piece error_file_name,
|
||||
const std::unordered_set<std::string>& used_source_files);
|
||||
|
||||
// Returns the final file name to be used for the output file.
|
||||
//
|
||||
// If an output file name is specified by the SetOutputFileName(), use that
|
||||
// argument as the final output file name.
|
||||
//
|
||||
// If the user did not specify an output filename:
|
||||
// If linking is not required, and the input filename has a
|
||||
// standard stage extension (e.g. .vert) then returns the input filename
|
||||
// without directory names but with the result extenstion (e.g. .spv or
|
||||
// .spvasm) appended.
|
||||
//
|
||||
// If linking is not required, and the input file name does not have a
|
||||
// standard stage extension, then also returns the directory-stripped input
|
||||
// filename, but replaces its extension with the result extension. (If the
|
||||
// resolved input filename does not have an extension, then appends the
|
||||
// result extension.)
|
||||
//
|
||||
// If linking is required and output filename is not specified, returns
|
||||
// "a.spv".
|
||||
std::string GetOutputFileName(std::string input_filename);
|
||||
|
||||
// Returns the candidate output file name deduced from input file name and
|
||||
// user specified output file name. It is computed as follows:
|
||||
//
|
||||
// If the user did specify an output filename and the compiler is not in
|
||||
// preprocessing-only mode, then returns that file name.
|
||||
//
|
||||
// If the user did not specify an output filename:
|
||||
// If the input filename has a standard stage extension (e.g. .vert) then
|
||||
// returns the input filename without directory names but with the result
|
||||
// extenstion (e.g. .spv or .spvasm) appended.
|
||||
//
|
||||
// If the input file name does not have a standard stage extension, then also
|
||||
// returns the directory-stripped input filename, but replaces its extension
|
||||
// with the result extension. (If the resolved input filename does not have
|
||||
// an extension, then appends the result extension.)
|
||||
//
|
||||
// When a resolved extension is not available because the compiler is in
|
||||
// preprocessing-only mode or the compilation requires linking, use .spv as
|
||||
// the extension.
|
||||
std::string GetCandidateOutputFileName(std::string input_filename);
|
||||
|
||||
// Returns true if the compiler's output is preprocessed text.
|
||||
bool PreprocessingOnly() {
|
||||
return output_type_ == OutputType::PreprocessedText;
|
||||
}
|
||||
|
||||
// Performs actual SPIR-V compilation on the contents of input files.
|
||||
shaderc::Compiler compiler_;
|
||||
|
||||
// Reflects the command-line arguments and goes into
|
||||
// compiler_.CompileGlslToSpv().
|
||||
shaderc::CompileOptions options_;
|
||||
|
||||
// What kind of output will be produced?
|
||||
OutputType output_type_;
|
||||
|
||||
// The Flag to indicate to which format the output SPIR-V binary code should
|
||||
// be emitted.
|
||||
SpirvBinaryEmissionFormat binary_emission_format_;
|
||||
|
||||
// A FileFinder used to substitute #include directives in the source code.
|
||||
shaderc_util::FileFinder include_file_finder_;
|
||||
|
||||
// Indicates whether linking is needed to generate the final output.
|
||||
bool needs_linking_;
|
||||
|
||||
// The ownership of dependency dumping handler.
|
||||
std::unique_ptr<DependencyInfoDumpingHandler>
|
||||
dependency_info_dumping_handler_ = nullptr;
|
||||
|
||||
// Reflects the type of file being generated.
|
||||
std::string file_extension_;
|
||||
// Name of the file where the compilation output will go.
|
||||
shaderc_util::string_piece output_file_name_;
|
||||
|
||||
// Counts warnings encountered in all compilations via this object.
|
||||
size_t total_warnings_;
|
||||
// Counts errors encountered in all compilations via this object.
|
||||
size_t total_errors_;
|
||||
};
|
||||
} // namespace glslc
|
||||
#endif // GLSLC_FILE_COMPILER_H
|
||||
66
3rdparty/shaderc/glslc/src/file_includer.cc
vendored
Normal file
66
3rdparty/shaderc/glslc/src/file_includer.cc
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
// Copyright 2015 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "file_includer.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <utility>
|
||||
|
||||
#include "libshaderc_util/io_shaderc.h"
|
||||
|
||||
namespace glslc {
|
||||
|
||||
shaderc_include_result* MakeErrorIncludeResult(const char* message) {
|
||||
return new shaderc_include_result{"", 0, message, strlen(message)};
|
||||
}
|
||||
|
||||
FileIncluder::~FileIncluder() = default;
|
||||
|
||||
shaderc_include_result* FileIncluder::GetInclude(
|
||||
const char* requested_source, shaderc_include_type include_type,
|
||||
const char* requesting_source, size_t) {
|
||||
|
||||
const std::string full_path =
|
||||
(include_type == shaderc_include_type_relative)
|
||||
? file_finder_.FindRelativeReadableFilepath(requesting_source,
|
||||
requested_source)
|
||||
: file_finder_.FindReadableFilepath(requested_source);
|
||||
|
||||
if (full_path.empty())
|
||||
return MakeErrorIncludeResult("Cannot find or open include file.");
|
||||
|
||||
// In principle, several threads could be resolving includes at the same
|
||||
// time. Protect the included_files.
|
||||
|
||||
// Read the file and save its full path and contents into stable addresses.
|
||||
FileInfo* new_file_info = new FileInfo{full_path, {}};
|
||||
if (!shaderc_util::ReadFile(full_path, &(new_file_info->contents))) {
|
||||
return MakeErrorIncludeResult("Cannot read file");
|
||||
}
|
||||
|
||||
included_files_.insert(full_path);
|
||||
|
||||
return new shaderc_include_result{
|
||||
new_file_info->full_path.data(), new_file_info->full_path.length(),
|
||||
new_file_info->contents.data(), new_file_info->contents.size(),
|
||||
new_file_info};
|
||||
}
|
||||
|
||||
void FileIncluder::ReleaseInclude(shaderc_include_result* include_result) {
|
||||
FileInfo* info = static_cast<FileInfo*>(include_result->user_data);
|
||||
delete info;
|
||||
delete include_result;
|
||||
}
|
||||
|
||||
} // namespace glslc
|
||||
74
3rdparty/shaderc/glslc/src/file_includer.h
vendored
Normal file
74
3rdparty/shaderc/glslc/src/file_includer.h
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright 2015 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef GLSLC_FILE_INCLUDER_H_
|
||||
#define GLSLC_FILE_INCLUDER_H_
|
||||
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "libshaderc_util/file_finder.h"
|
||||
#include "shaderc/shaderc.hpp"
|
||||
|
||||
namespace glslc {
|
||||
|
||||
// An includer for files implementing shaderc's includer interface. It responds
|
||||
// to the file including query from the compiler with the full path and content
|
||||
// of the file to be included. In the case that the file is not found or cannot
|
||||
// be opened, the full path field of in the response will point to an empty
|
||||
// string, and error message will be passed to the content field.
|
||||
// This class provides the basic thread-safety guarantee.
|
||||
class FileIncluder : public shaderc::CompileOptions::IncluderInterface {
|
||||
public:
|
||||
explicit FileIncluder(const shaderc_util::FileFinder* file_finder)
|
||||
: file_finder_(*file_finder) {}
|
||||
|
||||
~FileIncluder() override;
|
||||
|
||||
// Resolves a requested source file of a given type from a requesting
|
||||
// source into a shaderc_include_result whose contents will remain valid
|
||||
// until it's released.
|
||||
shaderc_include_result* GetInclude(const char* requested_source,
|
||||
shaderc_include_type type,
|
||||
const char* requesting_source,
|
||||
size_t include_depth) override;
|
||||
// Releases an include result.
|
||||
void ReleaseInclude(shaderc_include_result* include_result) override;
|
||||
|
||||
// Returns a reference to the member storing the set of included files.
|
||||
const std::unordered_set<std::string>& file_path_trace() const {
|
||||
return included_files_;
|
||||
}
|
||||
|
||||
private:
|
||||
// Used by GetInclude() to get the full filepath.
|
||||
const shaderc_util::FileFinder& file_finder_;
|
||||
// The full path and content of a source file.
|
||||
struct FileInfo {
|
||||
const std::string full_path;
|
||||
std::vector<char> contents;
|
||||
};
|
||||
|
||||
// The set of full paths of included files.
|
||||
std::unordered_set<std::string> included_files_;
|
||||
};
|
||||
|
||||
} // namespace glslc
|
||||
|
||||
#endif // GLSLC_FILE_INCLUDER_H_
|
||||
96
3rdparty/shaderc/glslc/src/file_test.cc
vendored
Normal file
96
3rdparty/shaderc/glslc/src/file_test.cc
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
// Copyright 2015 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "file.h"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using glslc::GetFileExtension;
|
||||
using glslc::IsStageFile;
|
||||
using glslc::GetGlslOrHlslExtension;
|
||||
using shaderc_util::string_piece;
|
||||
using testing::Eq;
|
||||
|
||||
class FileExtensionTest : public testing::Test {
|
||||
protected:
|
||||
string_piece empty = "";
|
||||
string_piece dot = ".";
|
||||
string_piece no_ext = "shader";
|
||||
string_piece trailing_dot = "shader.";
|
||||
string_piece vert_ext = "shader.vert";
|
||||
string_piece frag_ext = "shader.frag";
|
||||
string_piece tesc_ext = "shader.tesc";
|
||||
string_piece tese_ext = "shader.tese";
|
||||
string_piece geom_ext = "shader.geom";
|
||||
string_piece comp_ext = "shader.comp";
|
||||
string_piece glsl_ext = "shader.glsl";
|
||||
string_piece hlsl_ext = "shader.hlsl";
|
||||
string_piece multi_dot = "shader.some..ext";
|
||||
string_piece both_hg_ext = "shader.hlsl.glsl";
|
||||
string_piece both_gh_ext = "shader.glsl.hlsl";
|
||||
};
|
||||
|
||||
TEST_F(FileExtensionTest, GetFileExtension) {
|
||||
EXPECT_EQ("", GetFileExtension(empty));
|
||||
EXPECT_EQ("", GetFileExtension(dot));
|
||||
EXPECT_EQ("", GetFileExtension(no_ext));
|
||||
EXPECT_EQ("", GetFileExtension(trailing_dot));
|
||||
EXPECT_EQ("vert", GetFileExtension(vert_ext));
|
||||
EXPECT_EQ("frag", GetFileExtension(frag_ext));
|
||||
EXPECT_EQ("tesc", GetFileExtension(tesc_ext));
|
||||
EXPECT_EQ("tese", GetFileExtension(tese_ext));
|
||||
EXPECT_EQ("geom", GetFileExtension(geom_ext));
|
||||
EXPECT_EQ("comp", GetFileExtension(comp_ext));
|
||||
EXPECT_EQ("glsl", GetFileExtension(glsl_ext));
|
||||
EXPECT_EQ("ext", GetFileExtension(multi_dot));
|
||||
EXPECT_EQ("glsl", GetFileExtension(both_hg_ext));
|
||||
EXPECT_EQ("hlsl", GetFileExtension(both_gh_ext));
|
||||
}
|
||||
|
||||
TEST_F(FileExtensionTest, GetGlslOrHlslExtension) {
|
||||
EXPECT_THAT(GetGlslOrHlslExtension(empty), Eq(""));
|
||||
EXPECT_THAT(GetGlslOrHlslExtension(dot), Eq(""));
|
||||
EXPECT_THAT(GetGlslOrHlslExtension(no_ext), Eq(""));
|
||||
EXPECT_THAT(GetGlslOrHlslExtension(trailing_dot), Eq(""));
|
||||
EXPECT_THAT(GetGlslOrHlslExtension(vert_ext), Eq(""));
|
||||
EXPECT_THAT(GetGlslOrHlslExtension(frag_ext), Eq(""));
|
||||
EXPECT_THAT(GetGlslOrHlslExtension(tesc_ext), Eq(""));
|
||||
EXPECT_THAT(GetGlslOrHlslExtension(tese_ext), Eq(""));
|
||||
EXPECT_THAT(GetGlslOrHlslExtension(geom_ext), Eq(""));
|
||||
EXPECT_THAT(GetGlslOrHlslExtension(comp_ext), Eq(""));
|
||||
EXPECT_THAT(GetGlslOrHlslExtension(glsl_ext), Eq("glsl"));
|
||||
EXPECT_THAT(GetGlslOrHlslExtension(hlsl_ext), Eq("hlsl"));
|
||||
EXPECT_THAT(GetGlslOrHlslExtension(multi_dot), Eq(""));
|
||||
EXPECT_THAT(GetGlslOrHlslExtension(both_hg_ext), Eq("glsl"));
|
||||
EXPECT_THAT(GetGlslOrHlslExtension(both_gh_ext), Eq("hlsl"));
|
||||
}
|
||||
|
||||
TEST_F(FileExtensionTest, IsStageFile) {
|
||||
EXPECT_FALSE(IsStageFile(empty));
|
||||
EXPECT_FALSE(IsStageFile(dot));
|
||||
EXPECT_FALSE(IsStageFile(no_ext));
|
||||
EXPECT_FALSE(IsStageFile(trailing_dot));
|
||||
EXPECT_TRUE(IsStageFile(vert_ext));
|
||||
EXPECT_TRUE(IsStageFile(frag_ext));
|
||||
EXPECT_TRUE(IsStageFile(tesc_ext));
|
||||
EXPECT_TRUE(IsStageFile(tese_ext));
|
||||
EXPECT_TRUE(IsStageFile(geom_ext));
|
||||
EXPECT_TRUE(IsStageFile(comp_ext));
|
||||
EXPECT_FALSE(IsStageFile(glsl_ext));
|
||||
EXPECT_FALSE(IsStageFile(multi_dot));
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
695
3rdparty/shaderc/glslc/src/main.cc
vendored
Normal file
695
3rdparty/shaderc/glslc/src/main.cc
vendored
Normal file
@@ -0,0 +1,695 @@
|
||||
// Copyright 2015 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include "file.h"
|
||||
#include "file_compiler.h"
|
||||
#include "libshaderc_util/args.h"
|
||||
#include "libshaderc_util/compiler.h"
|
||||
#include "libshaderc_util/io_shaderc.h"
|
||||
#include "libshaderc_util/string_piece.h"
|
||||
#include "resource_parse.h"
|
||||
#include "shader_stage.h"
|
||||
#include "shaderc/env.h"
|
||||
#include "shaderc/shaderc.h"
|
||||
#include "spirv-tools/libspirv.h"
|
||||
|
||||
using shaderc_util::string_piece;
|
||||
|
||||
namespace {
|
||||
|
||||
// Prints the help message.
|
||||
void PrintHelp(std::ostream* out) {
|
||||
*out << R"(glslc - Compile shaders into SPIR-V
|
||||
|
||||
Usage: glslc [options] file...
|
||||
|
||||
An input file of - represents standard input.
|
||||
|
||||
Options:
|
||||
-c Only run preprocess, compile, and assemble steps.
|
||||
-Dmacro[=defn] Add an implicit macro definition.
|
||||
-E Outputs only the results of the preprocessing step.
|
||||
Output defaults to standard output.
|
||||
-fauto-bind-uniforms
|
||||
Automatically assign bindings to uniform variables that
|
||||
don't have an explicit 'binding' layout in the shader
|
||||
source.
|
||||
-fauto-map-locations
|
||||
Automatically assign locations to uniform variables that
|
||||
don't have an explicit 'location' layout in the shader
|
||||
source.
|
||||
-fauto-combined-image-sampler
|
||||
Removes sampler variables and converts existing textures
|
||||
to combined image-samplers.
|
||||
-fentry-point=<name>
|
||||
Specify the entry point name for HLSL compilation, for
|
||||
all subsequent source files. Default is "main".
|
||||
-fhlsl-16bit-types
|
||||
Enable 16-bit type support for HLSL.
|
||||
-fhlsl_functionality1, -fhlsl-functionality1
|
||||
Enable extension SPV_GOOGLE_hlsl_functionality1 for HLSL
|
||||
compilation.
|
||||
-fhlsl-iomap Use HLSL IO mappings for bindings.
|
||||
-fhlsl-offsets Use HLSL offset rules for packing members of blocks.
|
||||
Affects only GLSL. HLSL rules are always used for HLSL.
|
||||
-finvert-y Invert position.Y output in vertex shader.
|
||||
-flimit=<settings>
|
||||
Specify resource limits. Each limit is specified by a limit
|
||||
name followed by an integer value. Tokens should be
|
||||
separated by whitespace. If the same limit is specified
|
||||
several times, only the last setting takes effect.
|
||||
-flimit-file <file>
|
||||
Set limits as specified in the given file.
|
||||
-fnan-clamp Generate code for max and min builtins so that, when given
|
||||
a NaN operand, the other operand is returned. Similarly,
|
||||
the clamp builtin will favour the non-NaN operands, as if
|
||||
clamp were implemented as a composition of max and min.
|
||||
-fpreserve-bindings
|
||||
Preserve all binding declarations, even if those bindings
|
||||
are not used.
|
||||
-fresource-set-binding [stage] <reg0> <set0> <binding0>
|
||||
[<reg1> <set1> <binding1>...]
|
||||
Explicitly sets the descriptor set and binding for
|
||||
HLSL resources, by register name. Optionally restrict
|
||||
it to a single stage.
|
||||
-fcbuffer-binding-base [stage] <value>
|
||||
Same as -fubo-binding-base.
|
||||
-fimage-binding-base [stage] <value>
|
||||
Sets the lowest automatically assigned binding number for
|
||||
images. Optionally only set it for a single shader stage.
|
||||
For HLSL, the resource register number is added to this
|
||||
base.
|
||||
-fsampler-binding-base [stage] <value>
|
||||
Sets the lowest automatically assigned binding number for
|
||||
samplers Optionally only set it for a single shader stage.
|
||||
For HLSL, the resource register number is added to this
|
||||
base.
|
||||
-fssbo-binding-base [stage] <value>
|
||||
Sets the lowest automatically assigned binding number for
|
||||
shader storage buffer objects (SSBO). Optionally only set
|
||||
it for a single shader stage. Only affects GLSL.
|
||||
-ftexture-binding-base [stage] <value>
|
||||
Sets the lowest automatically assigned binding number for
|
||||
textures. Optionally only set it for a single shader stage.
|
||||
For HLSL, the resource register number is added to this
|
||||
base.
|
||||
-fuav-binding-base [stage] <value>
|
||||
For automatically assigned bindings for unordered access
|
||||
views (UAV), the register number is added to this base to
|
||||
determine the binding number. Optionally only set it for
|
||||
a single shader stage. Only affects HLSL.
|
||||
-fubo-binding-base [stage] <value>
|
||||
Sets the lowest automatically assigned binding number for
|
||||
uniform buffer objects (UBO). Optionally only set it for
|
||||
a single shader stage.
|
||||
For HLSL, the resource register number is added to this
|
||||
base.
|
||||
-fshader-stage=<stage>
|
||||
Treat subsequent input files as having stage <stage>.
|
||||
Valid stages are vertex, vert, fragment, frag, tesscontrol,
|
||||
tesc, tesseval, tese, geometry, geom, compute, and comp.
|
||||
-g Generate source-level debug information.
|
||||
-h Display available options.
|
||||
--help Display available options.
|
||||
-I <value> Add directory to include search path.
|
||||
-mfmt=<format> Output SPIR-V binary code using the selected format. This
|
||||
option may be specified only when the compilation output is
|
||||
in SPIR-V binary code form. Available options are:
|
||||
bin - SPIR-V binary words. This is the default.
|
||||
c - Binary words as C initializer list of 32-bit ints
|
||||
num - List of comma-separated 32-bit hex integers
|
||||
-M Generate make dependencies. Implies -E and -w.
|
||||
-MM An alias for -M.
|
||||
-MD Generate make dependencies and compile.
|
||||
-MF <file> Write dependency output to the given file.
|
||||
-MT <target> Specify the target of the rule emitted by dependency
|
||||
generation.
|
||||
-O Optimize the generated SPIR-V code for better performance.
|
||||
-Os Optimize the generated SPIR-V code for smaller size.
|
||||
-O0 Disable optimization.
|
||||
-o <file> Write output to <file>.
|
||||
A file name of '-' represents standard output.
|
||||
-std=<value> Version and profile for GLSL input files. Possible values
|
||||
are concatenations of version and profile, e.g. 310es,
|
||||
450core, etc. Ignored for HLSL files.
|
||||
-S Emit SPIR-V assembly instead of binary.
|
||||
--show-limits Display available limit names and their default values.
|
||||
--target-env=<environment>
|
||||
Set the target client environment, and the semantics
|
||||
of warnings and errors. An optional suffix can specify
|
||||
the client version. Values are:
|
||||
vulkan1.0 # The default
|
||||
vulkan1.1
|
||||
vulkan1.2
|
||||
vulkan1.3
|
||||
vulkan # Same as vulkan1.0
|
||||
opengl4.5
|
||||
opengl # Same as opengl4.5
|
||||
--target-spv=<spirv-version>
|
||||
Set the SPIR-V version to be used for the generated SPIR-V
|
||||
module. The default is the highest version of SPIR-V
|
||||
required to be supported for the target environment.
|
||||
For example, default for vulkan1.0 is spv1.0, and
|
||||
the default for vulkan1.1 is spv1.3,
|
||||
the default for vulkan1.2 is spv1.5.
|
||||
the default for vulkan1.3 is spv1.6.
|
||||
Values are:
|
||||
spv1.0, spv1.1, spv1.2, spv1.3, spv1.4, spv1.5, spv1.6
|
||||
--version Display compiler version information.
|
||||
-w Suppresses all warning messages.
|
||||
-Werror Treat all warnings as errors.
|
||||
-x <language> Treat subsequent input files as having type <language>.
|
||||
Valid languages are: glsl, hlsl.
|
||||
For files ending in .hlsl the default is hlsl.
|
||||
Otherwise the default is glsl.
|
||||
)";
|
||||
}
|
||||
|
||||
// Sets resource limits according to the given string. The string
|
||||
// should be formated as required for ParseResourceSettings.
|
||||
// Returns true on success. Otherwise returns false and sets err
|
||||
// to a descriptive error message.
|
||||
bool SetResourceLimits(const std::string& str, shaderc::CompileOptions* options,
|
||||
std::string* err) {
|
||||
std::vector<glslc::ResourceSetting> settings;
|
||||
if (!ParseResourceSettings(str, &settings, err)) {
|
||||
return false;
|
||||
}
|
||||
for (const auto& setting : settings) {
|
||||
options->SetLimit(setting.limit, setting.value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const char kBuildVersion[] =
|
||||
#include "build-version.inc"
|
||||
;
|
||||
|
||||
// Gets an optional stage name followed by required offset argument. Returns
|
||||
// false and emits a message to *errs if any errors occur. After calling this
|
||||
// function, *index will be the index of the last command line argument
|
||||
// consumed. If no stage name is provided, then *stage contains
|
||||
// shaderc_glsl_infer_from_source.
|
||||
bool GetOptionalStageThenOffsetArgument(const shaderc_util::string_piece option,
|
||||
std::ostream* errs, int argc,
|
||||
char** argv, int* index,
|
||||
shaderc_shader_kind* shader_kind,
|
||||
uint32_t* offset) {
|
||||
int& argi = *index;
|
||||
if (argi + 1 >= argc) {
|
||||
*errs << "glslc: error: Option " << option
|
||||
<< " requires at least one argument" << std::endl;
|
||||
return false;
|
||||
}
|
||||
auto stage = glslc::MapStageNameToForcedKind(argv[argi + 1]);
|
||||
if (stage != shaderc_glsl_infer_from_source) {
|
||||
++argi;
|
||||
if (argi + 1 >= argc) {
|
||||
*errs << "glslc: error: Option " << option << " with stage "
|
||||
<< argv[argi - 1] << " requires an offset argument" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!shaderc_util::ParseUint32(argv[argi + 1], offset)) {
|
||||
*errs << "glslc: error: invalid offset value " << argv[argi + 1] << " for "
|
||||
<< option << std::endl;
|
||||
return false;
|
||||
}
|
||||
++argi;
|
||||
*shader_kind = stage;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
std::vector<glslc::InputFileSpec> input_files;
|
||||
shaderc_shader_kind current_fshader_stage = shaderc_glsl_infer_from_source;
|
||||
bool source_language_forced = false;
|
||||
shaderc_source_language current_source_language =
|
||||
shaderc_source_language_glsl;
|
||||
std::string current_entry_point_name("main");
|
||||
glslc::FileCompiler compiler;
|
||||
bool success = true;
|
||||
bool has_stdin_input = false;
|
||||
// Shader stage for a single option.
|
||||
shaderc_shader_kind arg_stage = shaderc_glsl_infer_from_source;
|
||||
// Binding base for a single option.
|
||||
uint32_t arg_base = 0;
|
||||
|
||||
// What kind of uniform variable are we setting the binding base for?
|
||||
shaderc_uniform_kind u_kind = shaderc_uniform_kind_buffer;
|
||||
|
||||
// Sets binding base for the given uniform kind. If stage is
|
||||
// shader_glsl_infer_from_source then set it for all shader stages.
|
||||
auto set_binding_base = [&compiler](
|
||||
shaderc_shader_kind stage, shaderc_uniform_kind kind, uint32_t base) {
|
||||
if (stage == shaderc_glsl_infer_from_source)
|
||||
compiler.options().SetBindingBase(kind, base);
|
||||
else
|
||||
compiler.options().SetBindingBaseForStage(stage, kind, base);
|
||||
};
|
||||
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
const string_piece arg = argv[i];
|
||||
if (arg == "--help" || arg == "-h") {
|
||||
::PrintHelp(&std::cout);
|
||||
return 0;
|
||||
} else if (arg == "--show-limits") {
|
||||
shaderc_util::Compiler default_compiler;
|
||||
// The static cast here depends on us keeping the shaderc_limit enum in
|
||||
// lockstep with the shaderc_util::Compiler::Limit enum. The risk of mismatch
|
||||
// is low since both are generated from the same resources.inc file.
|
||||
#define RESOURCE(NAME, FIELD, ENUM) \
|
||||
std::cout << #NAME << " " \
|
||||
<< default_compiler.GetLimit( \
|
||||
static_cast<shaderc_util::Compiler::Limit>( \
|
||||
shaderc_limit_##ENUM)) \
|
||||
<< std::endl;
|
||||
#include "libshaderc_util/resources.inc"
|
||||
#undef RESOURCE
|
||||
return 0;
|
||||
} else if (arg == "--version") {
|
||||
std::cout << kBuildVersion << std::endl;
|
||||
std::cout << "Target: " << spvTargetEnvDescription(SPV_ENV_UNIVERSAL_1_0)
|
||||
<< std::endl;
|
||||
return 0;
|
||||
} else if (arg.starts_with("-o")) {
|
||||
string_piece file_name;
|
||||
if (!shaderc_util::GetOptionArgument(argc, argv, &i, "-o", &file_name)) {
|
||||
std::cerr
|
||||
<< "glslc: error: argument to '-o' is missing (expected 1 value)"
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
compiler.SetOutputFileName(file_name);
|
||||
} else if (arg.starts_with("-fshader-stage=")) {
|
||||
const string_piece stage = arg.substr(std::strlen("-fshader-stage="));
|
||||
current_fshader_stage = glslc::GetForcedShaderKindFromCmdLine(arg);
|
||||
if (current_fshader_stage == shaderc_glsl_infer_from_source) {
|
||||
std::cerr << "glslc: error: stage not recognized: '" << stage << "'"
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
} else if (arg == "-fauto-bind-uniforms") {
|
||||
compiler.options().SetAutoBindUniforms(true);
|
||||
} else if (arg == "-fauto-combined-image-sampler") {
|
||||
compiler.options().SetAutoSampledTextures(true);
|
||||
} else if (arg == "-fauto-map-locations") {
|
||||
compiler.options().SetAutoMapLocations(true);
|
||||
} else if (arg == "-fhlsl-iomap") {
|
||||
compiler.options().SetHlslIoMapping(true);
|
||||
} else if (arg == "-fhlsl-offsets") {
|
||||
compiler.options().SetHlslOffsets(true);
|
||||
} else if (arg == "-fhlsl_functionality1" ||
|
||||
arg == "-fhlsl-functionality1") {
|
||||
compiler.options().SetHlslFunctionality1(true);
|
||||
} else if (arg == "-fhlsl-16bit-types") {
|
||||
compiler.options().SetHlsl16BitTypes(true);
|
||||
} else if (arg == "-finvert-y") {
|
||||
compiler.options().SetInvertY(true);
|
||||
} else if (arg == "-fnan-clamp") {
|
||||
compiler.options().SetNanClamp(true);
|
||||
} else if (arg.starts_with("-fpreserve-bindings")) {
|
||||
compiler.options().SetPreserveBindings(true);
|
||||
} else if (((u_kind = shaderc_uniform_kind_image),
|
||||
(arg == "-fimage-binding-base")) ||
|
||||
((u_kind = shaderc_uniform_kind_texture),
|
||||
(arg == "-ftexture-binding-base")) ||
|
||||
((u_kind = shaderc_uniform_kind_sampler),
|
||||
(arg == "-fsampler-binding-base")) ||
|
||||
((u_kind = shaderc_uniform_kind_buffer),
|
||||
(arg == "-fubo-binding-base")) ||
|
||||
((u_kind = shaderc_uniform_kind_buffer),
|
||||
(arg == "-fcbuffer-binding-base")) ||
|
||||
((u_kind = shaderc_uniform_kind_storage_buffer),
|
||||
(arg == "-fssbo-binding-base")) ||
|
||||
((u_kind = shaderc_uniform_kind_unordered_access_view),
|
||||
(arg == "-fuav-binding-base"))) {
|
||||
if (!GetOptionalStageThenOffsetArgument(arg, &std::cerr, argc, argv, &i,
|
||||
&arg_stage, &arg_base))
|
||||
return 1;
|
||||
set_binding_base(arg_stage, u_kind, arg_base);
|
||||
} else if (arg == "-fresource-set-binding") {
|
||||
auto need_three_args_err = []() {
|
||||
std::cerr << "glsc: error: Option -fresource-set-binding"
|
||||
<< " requires at least 3 arguments" << std::endl;
|
||||
return 1;
|
||||
};
|
||||
if (i + 1 >= argc) return need_three_args_err();
|
||||
auto stage = glslc::MapStageNameToForcedKind(argv[i + 1]);
|
||||
if (stage != shaderc_glsl_infer_from_source) {
|
||||
++i;
|
||||
}
|
||||
bool seen_triple = false;
|
||||
while (i + 3 < argc && argv[i + 1][0] != '-' && argv[i + 2][0] != '-' &&
|
||||
argv[i + 3][0] != '-') {
|
||||
seen_triple = true;
|
||||
uint32_t set = 0;
|
||||
if (!shaderc_util::ParseUint32(argv[i + 2], &set)) {
|
||||
std::cerr << "glslc: error: Invalid set number: " << argv[i + 2]
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
uint32_t binding = 0;
|
||||
if (!shaderc_util::ParseUint32(argv[i + 3], &binding)) {
|
||||
std::cerr << "glslc: error: Invalid binding number: " << argv[i + 3]
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
if (stage == shaderc_glsl_infer_from_source) {
|
||||
compiler.options().SetHlslRegisterSetAndBinding(
|
||||
argv[i + 1], argv[i + 2], argv[i + 3]);
|
||||
} else {
|
||||
compiler.options().SetHlslRegisterSetAndBindingForStage(
|
||||
stage, argv[i + 1], argv[i + 2], argv[i + 3]);
|
||||
}
|
||||
i += 3;
|
||||
}
|
||||
if (!seen_triple) return need_three_args_err();
|
||||
} else if (arg.starts_with("-fentry-point=")) {
|
||||
current_entry_point_name =
|
||||
arg.substr(std::strlen("-fentry-point=")).str();
|
||||
} else if (arg.starts_with("-flimit=")) {
|
||||
std::string err;
|
||||
if (!SetResourceLimits(arg.substr(std::strlen("-flimit=")).str(),
|
||||
&compiler.options(), &err)) {
|
||||
std::cerr << "glslc: error: -flimit error: " << err << std::endl;
|
||||
return 1;
|
||||
}
|
||||
} else if (arg.starts_with("-flimit-file")) {
|
||||
std::string err;
|
||||
string_piece limits_file;
|
||||
if (!shaderc_util::GetOptionArgument(argc, argv, &i, "-flimit-file",
|
||||
&limits_file)) {
|
||||
std::cerr << "glslc: error: argument to '-flimit-file' is missing"
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::vector<char> contents;
|
||||
if (!shaderc_util::ReadFile(limits_file.str(), &contents)) {
|
||||
std::cerr << "glslc: cannot read limits file: " << limits_file
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
if (!SetResourceLimits(
|
||||
string_piece(contents.data(), contents.data() + contents.size())
|
||||
.str(),
|
||||
&compiler.options(), &err)) {
|
||||
std::cerr << "glslc: error: -flimit-file error: " << err << std::endl;
|
||||
return 1;
|
||||
}
|
||||
} else if (arg.starts_with("-std=")) {
|
||||
const string_piece standard = arg.substr(std::strlen("-std="));
|
||||
int version;
|
||||
shaderc_profile profile;
|
||||
if (!shaderc_parse_version_profile(standard.begin(), &version,
|
||||
&profile)) {
|
||||
std::cerr << "glslc: error: invalid value '" << standard
|
||||
<< "' in '-std=" << standard << "'" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
compiler.options().SetForcedVersionProfile(version, profile);
|
||||
} else if (arg.starts_with("--target-env=")) {
|
||||
shaderc_target_env target_env = shaderc_target_env_default;
|
||||
const string_piece target_env_str =
|
||||
arg.substr(std::strlen("--target-env="));
|
||||
uint32_t version = 0; // Will default appropriately.
|
||||
if (target_env_str == "vulkan") {
|
||||
target_env = shaderc_target_env_vulkan;
|
||||
} else if (target_env_str == "vulkan1.0") {
|
||||
target_env = shaderc_target_env_vulkan;
|
||||
version = shaderc_env_version_vulkan_1_0;
|
||||
} else if (target_env_str == "vulkan1.1") {
|
||||
target_env = shaderc_target_env_vulkan;
|
||||
version = shaderc_env_version_vulkan_1_1;
|
||||
} else if (target_env_str == "vulkan1.2") {
|
||||
target_env = shaderc_target_env_vulkan;
|
||||
version = shaderc_env_version_vulkan_1_2;
|
||||
} else if (target_env_str == "vulkan1.3") {
|
||||
target_env = shaderc_target_env_vulkan;
|
||||
version = shaderc_env_version_vulkan_1_3;
|
||||
} else if (target_env_str == "opengl") {
|
||||
target_env = shaderc_target_env_opengl;
|
||||
} else if (target_env_str == "opengl4.5") {
|
||||
target_env = shaderc_target_env_opengl;
|
||||
version = shaderc_env_version_opengl_4_5;
|
||||
} else if (target_env_str == "opengl_compat") {
|
||||
target_env = shaderc_target_env_opengl_compat;
|
||||
std::cerr << "glslc: error: opengl_compat is no longer supported"
|
||||
<< std::endl;
|
||||
return 1;
|
||||
} else {
|
||||
std::cerr << "glslc: error: invalid value '" << target_env_str
|
||||
<< "' in '--target-env=" << target_env_str << "'"
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
compiler.options().SetTargetEnvironment(target_env, version);
|
||||
} else if (arg.starts_with("--target-spv=")) {
|
||||
shaderc_spirv_version ver = shaderc_spirv_version_1_0;
|
||||
const string_piece ver_str = arg.substr(std::strlen("--target-spv="));
|
||||
if (ver_str == "spv1.0") {
|
||||
ver = shaderc_spirv_version_1_0;
|
||||
} else if (ver_str == "spv1.1") {
|
||||
ver = shaderc_spirv_version_1_1;
|
||||
} else if (ver_str == "spv1.2") {
|
||||
ver = shaderc_spirv_version_1_2;
|
||||
} else if (ver_str == "spv1.3") {
|
||||
ver = shaderc_spirv_version_1_3;
|
||||
} else if (ver_str == "spv1.4") {
|
||||
ver = shaderc_spirv_version_1_4;
|
||||
} else if (ver_str == "spv1.5") {
|
||||
ver = shaderc_spirv_version_1_5;
|
||||
} else if (ver_str == "spv1.6") {
|
||||
ver = shaderc_spirv_version_1_6;
|
||||
} else {
|
||||
std::cerr << "glslc: error: invalid value '" << ver_str
|
||||
<< "' in '--target-spv=" << ver_str << "'" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
compiler.options().SetTargetSpirv(ver);
|
||||
} else if (arg.starts_with("-mfmt=")) {
|
||||
const string_piece binary_output_format =
|
||||
arg.substr(std::strlen("-mfmt="));
|
||||
if (binary_output_format == "bin") {
|
||||
compiler.SetSpirvBinaryOutputFormat(
|
||||
glslc::FileCompiler::SpirvBinaryEmissionFormat::Binary);
|
||||
} else if (binary_output_format == "num") {
|
||||
compiler.SetSpirvBinaryOutputFormat(
|
||||
glslc::FileCompiler::SpirvBinaryEmissionFormat::Numbers);
|
||||
} else if (binary_output_format == "c") {
|
||||
compiler.SetSpirvBinaryOutputFormat(
|
||||
glslc::FileCompiler::SpirvBinaryEmissionFormat::CInitList);
|
||||
} else if (binary_output_format == "wgsl") {
|
||||
compiler.SetSpirvBinaryOutputFormat(
|
||||
glslc::FileCompiler::SpirvBinaryEmissionFormat::WGSL);
|
||||
} else {
|
||||
std::cerr << "glslc: error: invalid value '" << binary_output_format
|
||||
<< "' in '-mfmt=" << binary_output_format << "'" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
} else if (arg.starts_with("-x")) {
|
||||
string_piece option_arg;
|
||||
if (!shaderc_util::GetOptionArgument(argc, argv, &i, "-x", &option_arg)) {
|
||||
std::cerr
|
||||
<< "glslc: error: argument to '-x' is missing (expected 1 value)"
|
||||
<< std::endl;
|
||||
success = false;
|
||||
} else {
|
||||
if (option_arg == "glsl") {
|
||||
current_source_language = shaderc_source_language_glsl;
|
||||
} else if (option_arg == "hlsl") {
|
||||
current_source_language = shaderc_source_language_hlsl;
|
||||
} else {
|
||||
std::cerr << "glslc: error: language not recognized: '" << option_arg
|
||||
<< "'" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
source_language_forced = true;
|
||||
}
|
||||
} else if (arg == "-c") {
|
||||
compiler.SetIndividualCompilationFlag();
|
||||
} else if (arg == "-E") {
|
||||
compiler.SetPreprocessingOnlyFlag();
|
||||
} else if (arg == "-M" || arg == "-MM") {
|
||||
// -M implies -E and -w
|
||||
compiler.SetPreprocessingOnlyFlag();
|
||||
compiler.options().SetSuppressWarnings();
|
||||
if (compiler.GetDependencyDumpingHandler()->DumpingModeNotSet()) {
|
||||
compiler.GetDependencyDumpingHandler()
|
||||
->SetDumpAsNormalCompilationOutput();
|
||||
} else {
|
||||
std::cerr << "glslc: error: both -M (or -MM) and -MD are specified. "
|
||||
"Only one should be used at one time."
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
} else if (arg == "-MD") {
|
||||
if (compiler.GetDependencyDumpingHandler()->DumpingModeNotSet()) {
|
||||
compiler.GetDependencyDumpingHandler()
|
||||
->SetDumpToExtraDependencyInfoFiles();
|
||||
} else {
|
||||
std::cerr << "glslc: error: both -M (or -MM) and -MD are specified. "
|
||||
"Only one should be used at one time."
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
} else if (arg == "-MF") {
|
||||
string_piece dep_file_name;
|
||||
if (!shaderc_util::GetOptionArgument(argc, argv, &i, "-MF",
|
||||
&dep_file_name)) {
|
||||
std::cerr
|
||||
<< "glslc: error: missing dependency info filename after '-MF'"
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
compiler.GetDependencyDumpingHandler()->SetDependencyFileName(
|
||||
std::string(dep_file_name.data(), dep_file_name.size()));
|
||||
} else if (arg == "-MT") {
|
||||
string_piece dep_file_name;
|
||||
if (!shaderc_util::GetOptionArgument(argc, argv, &i, "-MT",
|
||||
&dep_file_name)) {
|
||||
std::cerr << "glslc: error: missing dependency info target after '-MT'"
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
compiler.GetDependencyDumpingHandler()->SetTarget(
|
||||
std::string(dep_file_name.data(), dep_file_name.size()));
|
||||
} else if (arg == "-S") {
|
||||
compiler.SetDisassemblyFlag();
|
||||
} else if (arg.starts_with("-D")) {
|
||||
const size_t length = arg.size();
|
||||
if (length <= 2) {
|
||||
std::cerr << "glslc: error: argument to '-D' is missing" << std::endl;
|
||||
} else {
|
||||
const string_piece argument = arg.substr(2);
|
||||
// Get the exact length of the macro string.
|
||||
size_t equal_sign_loc = argument.find_first_of('=');
|
||||
size_t name_length = equal_sign_loc != shaderc_util::string_piece::npos
|
||||
? equal_sign_loc
|
||||
: argument.size();
|
||||
const string_piece name_piece = argument.substr(0, name_length);
|
||||
if (name_piece.starts_with("GL_")) {
|
||||
std::cerr
|
||||
<< "glslc: error: names beginning with 'GL_' cannot be defined: "
|
||||
<< arg << std::endl;
|
||||
return 1;
|
||||
}
|
||||
if (name_piece.find("__") != string_piece::npos) {
|
||||
std::cerr
|
||||
<< "glslc: warning: names containing consecutive underscores "
|
||||
"are reserved: "
|
||||
<< arg << std::endl;
|
||||
}
|
||||
|
||||
const string_piece value_piece =
|
||||
(equal_sign_loc == string_piece::npos ||
|
||||
equal_sign_loc == argument.size() - 1)
|
||||
? ""
|
||||
: argument.substr(name_length + 1);
|
||||
// TODO(deki): check arg for newlines.
|
||||
compiler.options().AddMacroDefinition(
|
||||
name_piece.data(), name_piece.size(), value_piece.data(),
|
||||
value_piece.size());
|
||||
}
|
||||
} else if (arg.starts_with("-I")) {
|
||||
string_piece option_arg;
|
||||
if (!shaderc_util::GetOptionArgument(argc, argv, &i, "-I", &option_arg)) {
|
||||
std::cerr
|
||||
<< "glslc: error: argument to '-I' is missing (expected 1 value)"
|
||||
<< std::endl;
|
||||
success = false;
|
||||
} else {
|
||||
compiler.AddIncludeDirectory(option_arg.str());
|
||||
}
|
||||
} else if (arg == "-g") {
|
||||
compiler.options().SetGenerateDebugInfo();
|
||||
} else if (arg.starts_with("-O")) {
|
||||
if (arg == "-O") {
|
||||
compiler.options().SetOptimizationLevel(
|
||||
shaderc_optimization_level_performance);
|
||||
} else if (arg == "-Os") {
|
||||
compiler.options().SetOptimizationLevel(
|
||||
shaderc_optimization_level_size);
|
||||
} else if (arg == "-O0") {
|
||||
compiler.options().SetOptimizationLevel(
|
||||
shaderc_optimization_level_zero);
|
||||
} else {
|
||||
std::cerr << "glslc: error: invalid value '"
|
||||
<< arg.substr(std::strlen("-O")) << "' in '" << arg << "'"
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
} else if (arg == "-w") {
|
||||
compiler.options().SetSuppressWarnings();
|
||||
} else if (arg == "-Werror") {
|
||||
compiler.options().SetWarningsAsErrors();
|
||||
} else if (!(arg == "-") && arg[0] == '-') {
|
||||
std::cerr << "glslc: error: "
|
||||
<< (arg[1] == '-' ? "unsupported option" : "unknown argument")
|
||||
<< ": '" << arg << "'" << std::endl;
|
||||
return 1;
|
||||
} else {
|
||||
if (arg == "-") {
|
||||
if (has_stdin_input) {
|
||||
std::cerr << "glslc: error: specifying standard input \"-\" as input "
|
||||
<< "more than once is not allowed." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
has_stdin_input = true;
|
||||
}
|
||||
|
||||
const auto language = source_language_forced
|
||||
? current_source_language
|
||||
: ((glslc::GetFileExtension(arg) == "hlsl")
|
||||
? shaderc_source_language_hlsl
|
||||
: shaderc_source_language_glsl);
|
||||
|
||||
// If current_fshader_stage is shaderc_glsl_infer_from_source, that means
|
||||
// we didn't set forced shader kinds (otherwise an error should have
|
||||
// already been emitted before). So we should deduce the shader kind
|
||||
// from the file name. If current_fshader_stage is specifed to one of
|
||||
// the forced shader kinds, use that for the following compilation.
|
||||
input_files.emplace_back(glslc::InputFileSpec{
|
||||
arg.str(), (current_fshader_stage == shaderc_glsl_infer_from_source
|
||||
? glslc::DeduceDefaultShaderKindFromFileName(arg)
|
||||
: current_fshader_stage),
|
||||
language, current_entry_point_name});
|
||||
}
|
||||
}
|
||||
|
||||
if (!compiler.ValidateOptions(input_files.size())) return 1;
|
||||
|
||||
if (!success) return 1;
|
||||
|
||||
for (const auto& input_file : input_files) {
|
||||
success &= compiler.CompileShaderFile(input_file);
|
||||
}
|
||||
|
||||
compiler.OutputMessages();
|
||||
return success ? 0 : 1;
|
||||
}
|
||||
97
3rdparty/shaderc/glslc/src/resource_parse.cc
vendored
Normal file
97
3rdparty/shaderc/glslc/src/resource_parse.cc
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
// Copyright 2016 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "resource_parse.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
// Converts a limit string to a limit enum. Returns true on successful
|
||||
// conversion.
|
||||
bool StringToLimit(const std::string& str, shaderc_limit* limit) {
|
||||
const char* cstr = str.c_str();
|
||||
#define RESOURCE(NAME, FIELD, ENUM) \
|
||||
if (0 == std::strcmp(#NAME, cstr)) { \
|
||||
*limit = shaderc_limit_##ENUM; \
|
||||
return true; \
|
||||
}
|
||||
#include "libshaderc_util/resources.inc"
|
||||
#undef RESOURCE
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns true if we should ignore the setting.
|
||||
bool IgnoreSetting(const std::string& str) {
|
||||
const std::string ignore_list[] = {
|
||||
"nonInductiveForLoops",
|
||||
"whileLoops",
|
||||
"doWhileLoops",
|
||||
"generalUniformIndexing",
|
||||
"generalAttributeMatrixVectorIndexing",
|
||||
"generalVaryingIndexing",
|
||||
"generalSamplerIndexing",
|
||||
"generalVariableIndexing",
|
||||
"generalConstantMatrixVectorIndexing",
|
||||
};
|
||||
return std::find(std::begin(ignore_list), std::end(ignore_list), str) !=
|
||||
std::end(ignore_list);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace glslc {
|
||||
|
||||
bool ParseResourceSettings(const std::string& input,
|
||||
std::vector<ResourceSetting>* limits,
|
||||
std::string* err) {
|
||||
auto failure = [err, limits](std::string msg) {
|
||||
*err = msg;
|
||||
limits->clear();
|
||||
return false;
|
||||
};
|
||||
std::istringstream input_stream(input);
|
||||
std::istream_iterator<std::string> pos((input_stream));
|
||||
limits->clear();
|
||||
|
||||
while (pos != std::istream_iterator<std::string>()) {
|
||||
const std::string limit_name = *pos++;
|
||||
shaderc_limit limit = static_cast<shaderc_limit>(0);
|
||||
bool ignore = IgnoreSetting(limit_name);
|
||||
if (!ignore) {
|
||||
if (!StringToLimit(limit_name, &limit))
|
||||
return failure(std::string("invalid resource limit: " + limit_name));
|
||||
}
|
||||
|
||||
if (pos == std::istream_iterator<std::string>())
|
||||
return failure(std::string("missing value after limit: ") + limit_name);
|
||||
|
||||
const std::string value_str = *pos;
|
||||
int value;
|
||||
std::istringstream value_stream(value_str);
|
||||
value_stream >> value;
|
||||
if (value_stream.bad() || !value_stream.eof() || value_stream.fail())
|
||||
return failure(std::string("invalid integer: ") + value_str);
|
||||
|
||||
if (!ignore) limits->push_back({limit, value});
|
||||
++pos;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // anonymous namespace
|
||||
60
3rdparty/shaderc/glslc/src/resource_parse.h
vendored
Normal file
60
3rdparty/shaderc/glslc/src/resource_parse.h
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2016 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef GLSLC_RESOURCE_PARSE_H
|
||||
#define GLSLC_RESOURCE_PARSE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "shaderc/shaderc.h"
|
||||
|
||||
namespace glslc {
|
||||
|
||||
// A resource limit setting.
|
||||
struct ResourceSetting {
|
||||
shaderc_limit limit;
|
||||
int value;
|
||||
};
|
||||
|
||||
|
||||
// Returns true when two resource setting structures are equal.
|
||||
inline bool operator==(const ResourceSetting& lhs, const ResourceSetting& rhs) {
|
||||
return (lhs.limit == rhs.limit) && (lhs.value == rhs.value);
|
||||
}
|
||||
|
||||
|
||||
// Parses a resource limit setting string. On success, returns true and populates
|
||||
// the limits parameter. On failure returns failure and emits a message to err.
|
||||
// The setting string should be a seqeuence of pairs, where each pair
|
||||
// is a limit name followed by a decimal integer. Tokens should be separated
|
||||
// by whitespace. In particular, this function accepts Glslang's configuration
|
||||
// file syntax. If a limit is mentioned multiple times, then the last setting
|
||||
// takes effect. Ignore settings for:
|
||||
// nonInductiveForLoops
|
||||
// whileLoops
|
||||
// doWhileLoops
|
||||
// generalUniformIndexing
|
||||
// generalAttributeMatrixVectorIndexing
|
||||
// generalVaryingIndexing
|
||||
// generalSamplerIndexing
|
||||
// generalVariableIndexing
|
||||
// generalConstantMatrixVectorIndexing
|
||||
bool ParseResourceSettings(const std::string& input,
|
||||
std::vector<ResourceSetting>* limits,
|
||||
std::string* err);
|
||||
} // namespace glslc
|
||||
|
||||
|
||||
#endif // GLSLC_FILE_H_
|
||||
75
3rdparty/shaderc/glslc/src/resource_parse_test.cc
vendored
Normal file
75
3rdparty/shaderc/glslc/src/resource_parse_test.cc
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
// Copyright 2017 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "resource_parse.h"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using glslc::ParseResourceSettings;
|
||||
using glslc::ResourceSetting;
|
||||
using testing::Eq;
|
||||
|
||||
struct ResourceSettingsCase {
|
||||
std::string input;
|
||||
bool success;
|
||||
std::vector<ResourceSetting> settings;
|
||||
std::string message;
|
||||
};
|
||||
|
||||
using ParseResourceSettingsTest = ::testing::TestWithParam<ResourceSettingsCase>;
|
||||
|
||||
TEST_P(ParseResourceSettingsTest, Sample) {
|
||||
std::vector<ResourceSetting> settings;
|
||||
std::string err;
|
||||
const bool succeeded = ParseResourceSettings(GetParam().input, &settings, &err);
|
||||
EXPECT_THAT(succeeded, Eq(GetParam().success));
|
||||
EXPECT_THAT(settings, Eq(GetParam().settings));
|
||||
EXPECT_THAT(err, Eq(GetParam().message));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ParseResources, ParseResourceSettingsTest,
|
||||
::testing::ValuesIn(std::vector<ResourceSettingsCase>{
|
||||
{"", true, {}, ""},
|
||||
{" \t \t \n ", true, {}, ""},
|
||||
{" blorp blam", false, {}, "invalid resource limit: blorp"},
|
||||
{"MaxLightsxyz", false, {}, "invalid resource limit: MaxLightsxyz"},
|
||||
{"MaxLights", false, {}, "missing value after limit: MaxLights"},
|
||||
{"MaxLights x", false, {}, "invalid integer: x"},
|
||||
{"MaxLights 99x", false, {}, "invalid integer: 99x"},
|
||||
{"MaxLights 12 blam", false, {}, "invalid resource limit: blam"},
|
||||
{"MaxLights 12", true, {{shaderc_limit_max_lights, 12}}, ""},
|
||||
// Test negative number
|
||||
{"MinProgramTexelOffset -9", true, {{shaderc_limit_min_program_texel_offset, -9}}, ""},
|
||||
// Test leading, intervening, and trailing whitespace
|
||||
{" \tMaxLights \n 12 \t ", true, {{shaderc_limit_max_lights, 12}}, ""},
|
||||
// Test more than one limit setting.
|
||||
{"MinProgramTexelOffset -10 MaxLights 4", true, {{shaderc_limit_min_program_texel_offset, -10}, {shaderc_limit_max_lights, 4}}, ""},
|
||||
// Check ignore cases.
|
||||
{"nonInductiveForLoops", false, {}, "missing value after limit: nonInductiveForLoops"},
|
||||
{"nonInductiveForLoops 1", true, {}, ""},
|
||||
{"whileLoops 1", true, {}, ""},
|
||||
{"doWhileLoops 1", true, {}, ""},
|
||||
{"generalUniformIndexing 1", true, {}, ""},
|
||||
{"generalAttributeMatrixVectorIndexing 1", true, {}, ""},
|
||||
{"generalVaryingIndexing 1", true, {}, ""},
|
||||
{"generalSamplerIndexing 1", true, {}, ""},
|
||||
{"generalVariableIndexing 1", true, {}, ""},
|
||||
{"generalConstantMatrixVectorIndexing 1", true, {}, ""},
|
||||
// Check an ignore case with a regular case
|
||||
{"whileLoops 1 MaxLights 99", true, {{shaderc_limit_max_lights, 99}}, ""},
|
||||
}));
|
||||
|
||||
} // anonymous namespace
|
||||
100
3rdparty/shaderc/glslc/src/shader_stage.cc
vendored
Normal file
100
3rdparty/shaderc/glslc/src/shader_stage.cc
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
// Copyright 2015 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "shader_stage.h"
|
||||
|
||||
#include "file.h"
|
||||
|
||||
using shaderc_util::string_piece;
|
||||
|
||||
namespace {
|
||||
|
||||
// Maps an identifier to a shader stage.
|
||||
struct StageMapping {
|
||||
const char* id;
|
||||
shaderc_shader_kind stage;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace glslc {
|
||||
|
||||
shaderc_shader_kind MapStageNameToForcedKind(const string_piece& stage_name) {
|
||||
const StageMapping string_to_kind[] = {
|
||||
{"vertex", shaderc_glsl_vertex_shader},
|
||||
{"vert", shaderc_glsl_vertex_shader},
|
||||
{"fragment", shaderc_glsl_fragment_shader},
|
||||
{"frag", shaderc_glsl_fragment_shader},
|
||||
{"tesscontrol", shaderc_glsl_tess_control_shader},
|
||||
{"tesc", shaderc_glsl_tess_control_shader},
|
||||
{"tesseval", shaderc_glsl_tess_evaluation_shader},
|
||||
{"tese", shaderc_glsl_tess_evaluation_shader},
|
||||
{"geometry", shaderc_glsl_geometry_shader},
|
||||
{"geom", shaderc_glsl_geometry_shader},
|
||||
{"compute", shaderc_glsl_compute_shader},
|
||||
{"comp", shaderc_glsl_compute_shader},
|
||||
{"rgen", shaderc_glsl_raygen_shader },
|
||||
{"rahit", shaderc_glsl_anyhit_shader },
|
||||
{"rchit", shaderc_glsl_closesthit_shader },
|
||||
{"rmiss", shaderc_glsl_miss_shader },
|
||||
{"rint", shaderc_glsl_intersection_shader },
|
||||
{"rcall", shaderc_glsl_callable_shader },
|
||||
{"task", shaderc_glsl_task_shader },
|
||||
{"mesh", shaderc_glsl_mesh_shader },
|
||||
};
|
||||
for (const auto& entry : string_to_kind) {
|
||||
if (stage_name == entry.id) return entry.stage;
|
||||
}
|
||||
return shaderc_glsl_infer_from_source;
|
||||
}
|
||||
|
||||
shaderc_shader_kind GetForcedShaderKindFromCmdLine(
|
||||
const shaderc_util::string_piece& f_shader_stage_str) {
|
||||
size_t equal_pos = f_shader_stage_str.find_first_of("=");
|
||||
if (equal_pos == std::string::npos) return shaderc_glsl_infer_from_source;
|
||||
return MapStageNameToForcedKind(f_shader_stage_str.substr(equal_pos + 1));
|
||||
}
|
||||
|
||||
shaderc_shader_kind DeduceDefaultShaderKindFromFileName(
|
||||
const string_piece file_name) {
|
||||
// Add new stage types here.
|
||||
static const StageMapping kStringToStage[] = {
|
||||
{"vert", shaderc_glsl_default_vertex_shader},
|
||||
{"frag", shaderc_glsl_default_fragment_shader},
|
||||
{"tesc", shaderc_glsl_default_tess_control_shader},
|
||||
{"tese", shaderc_glsl_default_tess_evaluation_shader},
|
||||
{"geom", shaderc_glsl_default_geometry_shader},
|
||||
{"comp", shaderc_glsl_default_compute_shader},
|
||||
{"spvasm", shaderc_spirv_assembly},
|
||||
{"rgen", shaderc_glsl_default_raygen_shader },
|
||||
{"rahit", shaderc_glsl_default_anyhit_shader },
|
||||
{"rchit", shaderc_glsl_default_closesthit_shader },
|
||||
{"rmiss", shaderc_glsl_default_miss_shader },
|
||||
{"rint", shaderc_glsl_default_intersection_shader },
|
||||
{"rcall", shaderc_glsl_default_callable_shader },
|
||||
{"task", shaderc_glsl_default_task_shader },
|
||||
{"mesh", shaderc_glsl_default_mesh_shader },
|
||||
};
|
||||
|
||||
const string_piece extension = glslc::GetFileExtension(file_name);
|
||||
shaderc_shader_kind stage = shaderc_glsl_infer_from_source;
|
||||
|
||||
for (const auto& entry : kStringToStage) {
|
||||
if (extension == entry.id) stage = entry.stage;
|
||||
}
|
||||
|
||||
return stage;
|
||||
}
|
||||
|
||||
} // namespace glslc
|
||||
42
3rdparty/shaderc/glslc/src/shader_stage.h
vendored
Normal file
42
3rdparty/shaderc/glslc/src/shader_stage.h
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright 2015 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef GLSLC_SHADER_STAGE_H_
|
||||
#define GLSLC_SHADER_STAGE_H_
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "libshaderc_util/string_piece.h"
|
||||
#include "shaderc/shaderc.h"
|
||||
|
||||
namespace glslc {
|
||||
|
||||
// Maps a shader stage name to a forced shader stage enum value. Returns
|
||||
// 'shaderc_glsl_infer_from_source' if the stage name is unrecognized.
|
||||
shaderc_shader_kind MapStageNameToForcedKind(
|
||||
const shaderc_util::string_piece& f_shader_stage_str);
|
||||
|
||||
// Parse the string piece from command line to get the force shader stage.
|
||||
// If the 'f_shader_stage_str' cannot be parsed to a valid force shader stage,
|
||||
// returns 'shaderc_glsl_infer_from_source'. Requires the string to begin with
|
||||
// '='.
|
||||
shaderc_shader_kind GetForcedShaderKindFromCmdLine(
|
||||
const shaderc_util::string_piece& f_shader_stage_str);
|
||||
|
||||
// Parse the file name extension to get the default shader kind.
|
||||
shaderc_shader_kind DeduceDefaultShaderKindFromFileName(
|
||||
shaderc_util::string_piece file_name);
|
||||
} // namespace glslc
|
||||
|
||||
#endif // GLSLC_SHADER_STAGE_H_
|
||||
92
3rdparty/shaderc/glslc/src/stage_test.cc
vendored
Normal file
92
3rdparty/shaderc/glslc/src/stage_test.cc
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
// Copyright 2015 The Shaderc Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Some of the tests here check code paths that are not checked by
|
||||
// integration tests.
|
||||
// Generally, these would be conditions not generated by the Glslang
|
||||
// compiler. It's easier to write these unit tests than to inject
|
||||
// a dependency on a fake compiler.
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "shaderc/shaderc.h"
|
||||
|
||||
#include "shader_stage.h"
|
||||
|
||||
using shaderc_util::string_piece;
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(DeduceDefaultShaderKindFromFileName, ValidStage) {
|
||||
std::stringstream error_stream;
|
||||
EXPECT_EQ(shaderc_glsl_default_vertex_shader,
|
||||
glslc::DeduceDefaultShaderKindFromFileName("a.vert"));
|
||||
|
||||
EXPECT_EQ(shaderc_glsl_default_fragment_shader,
|
||||
glslc::DeduceDefaultShaderKindFromFileName("a.frag"));
|
||||
|
||||
EXPECT_EQ(shaderc_glsl_default_geometry_shader,
|
||||
glslc::DeduceDefaultShaderKindFromFileName("a.geom"));
|
||||
|
||||
EXPECT_EQ(shaderc_glsl_default_tess_control_shader,
|
||||
glslc::DeduceDefaultShaderKindFromFileName("a.tesc"));
|
||||
|
||||
EXPECT_EQ(shaderc_glsl_default_tess_evaluation_shader,
|
||||
glslc::DeduceDefaultShaderKindFromFileName("a.tese"));
|
||||
|
||||
EXPECT_EQ(shaderc_glsl_default_compute_shader,
|
||||
glslc::DeduceDefaultShaderKindFromFileName("a.comp"));
|
||||
|
||||
EXPECT_EQ(shaderc_glsl_default_raygen_shader,
|
||||
glslc::DeduceDefaultShaderKindFromFileName("a.rgen"));
|
||||
|
||||
EXPECT_EQ(shaderc_glsl_default_anyhit_shader,
|
||||
glslc::DeduceDefaultShaderKindFromFileName("a.rahit"));
|
||||
|
||||
EXPECT_EQ(shaderc_glsl_default_closesthit_shader,
|
||||
glslc::DeduceDefaultShaderKindFromFileName("a.rchit"));
|
||||
|
||||
EXPECT_EQ(shaderc_glsl_default_miss_shader,
|
||||
glslc::DeduceDefaultShaderKindFromFileName("a.rmiss"));
|
||||
|
||||
EXPECT_EQ(shaderc_glsl_default_intersection_shader,
|
||||
glslc::DeduceDefaultShaderKindFromFileName("a.rint"));
|
||||
|
||||
EXPECT_EQ(shaderc_glsl_default_callable_shader,
|
||||
glslc::DeduceDefaultShaderKindFromFileName("a.rcall"));
|
||||
|
||||
EXPECT_EQ(shaderc_glsl_default_task_shader,
|
||||
glslc::DeduceDefaultShaderKindFromFileName("a.task"));
|
||||
|
||||
EXPECT_EQ(shaderc_glsl_default_mesh_shader,
|
||||
glslc::DeduceDefaultShaderKindFromFileName("a.mesh"));
|
||||
}
|
||||
|
||||
TEST(DeduceDefaultShaderKindFromFileName, InvalidStage) {
|
||||
std::stringstream error_stream;
|
||||
EXPECT_EQ(shaderc_glsl_infer_from_source,
|
||||
glslc::DeduceDefaultShaderKindFromFileName("a.glsl"));
|
||||
|
||||
EXPECT_EQ(shaderc_glsl_infer_from_source,
|
||||
glslc::DeduceDefaultShaderKindFromFileName("-"));
|
||||
|
||||
EXPECT_EQ(shaderc_glsl_infer_from_source,
|
||||
glslc::DeduceDefaultShaderKindFromFileName("a.foo"));
|
||||
|
||||
EXPECT_EQ(shaderc_glsl_infer_from_source,
|
||||
glslc::DeduceDefaultShaderKindFromFileName("no-file-extension"));
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
Reference in New Issue
Block a user