First Commit

This commit is contained in:
2025-11-18 14:18:26 -07:00
parent 33eb6e3707
commit 27277ec342
6106 changed files with 3571167 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
// Copyright 2019 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 LIBSHADERC_UTIL_INC_ARGS_H
#define LIBSHADERC_UTIL_INC_ARGS_H
#include <cstdint>
#include <string>
#include "libshaderc_util/string_piece.h"
namespace shaderc_util {
// Gets the option argument for the option at *index in argv in a way consistent
// with clang/gcc. On success, returns true and writes the parsed argument into
// *option_argument. Returns false if any errors occur. After calling this
// function, *index will be the index of the last command line argument
// consumed.
bool GetOptionArgument(int argc, char** argv, int* index,
const std::string& option,
string_piece* option_argument);
// Parses the given string as a number of the specified type. Returns true
// if parsing succeeded, and stores the parsed value via |value|.
// (I've worked out the general case for this in
// SPIRV-Tools source/util/parse_number.h. -- dneto)
bool ParseUint32(const std::string& str, uint32_t* value);
} // namespace shaderc_util
#endif // LIBSHADERC_UTIL_INC_ARGS_H

View File

@@ -0,0 +1,656 @@
// 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 LIBSHADERC_UTIL_INC_COMPILER_H
#define LIBSHADERC_UTIL_INC_COMPILER_H
#include <array>
#include <cassert>
#include <functional>
#include <mutex>
#include <ostream>
#include <string>
#include <unordered_map>
#include <utility>
#include "glslang/Public/ShaderLang.h"
#include "counting_includer.h"
#include "file_finder.h"
#include "mutex.h"
#include "resources.h"
#include "string_piece.h"
// Fix a typo in glslang/Public/ShaderLang.h
#define EShTargetClientVersion EshTargetClientVersion
namespace shaderc_util {
// To break recursive including. This header is already included in
// spirv_tools_wrapper.h, so cannot include spirv_tools_wrapper.h here.
enum class PassId;
// Initializes glslang on creation, and destroys it on completion.
// Used to tie gslang process operations to object lifetimes.
// Additionally initialization/finalization of glslang is not thread safe, so
// synchronizes these operations.
class GlslangInitializer {
public:
GlslangInitializer();
~GlslangInitializer();
private:
static unsigned int initialize_count_;
// Using a bare pointer here to avoid any global class construction at the
// beginning of the execution.
static std::mutex* glslang_mutex_;
};
// Maps macro names to their definitions. Stores string_pieces, so the
// underlying strings must outlive it.
using MacroDictionary = std::unordered_map<std::string, std::string>;
// Holds all of the state required to compile source GLSL into SPIR-V.
class Compiler {
public:
// Source language
enum class SourceLanguage {
GLSL, // The default
HLSL,
};
// Target environment.
enum class TargetEnv {
Vulkan, // Default to Vulkan 1.0
OpenGL, // Default to OpenGL 4.5
OpenGLCompat, // Support removed. Generates error if used.
};
// Target environment versions. These numbers match those used by Glslang.
enum class TargetEnvVersion : uint32_t {
Default = 0, // Default for the corresponding target environment
// For Vulkan, use numbering scheme from vulkan.h
Vulkan_1_0 = ((1 << 22)), // Vulkan 1.0
Vulkan_1_1 = ((1 << 22) | (1 << 12)), // Vulkan 1.1
Vulkan_1_2 = ((1 << 22) | (2 << 12)), // Vulkan 1.2
Vulkan_1_3 = ((1 << 22) | (3 << 12)), // Vulkan 1.2
// For OpenGL, use the numbering from #version in shaders.
OpenGL_4_5 = 450,
};
// SPIR-V version.
enum class SpirvVersion : uint32_t {
v1_0 = 0x010000u,
v1_1 = 0x010100u,
v1_2 = 0x010200u,
v1_3 = 0x010300u,
v1_4 = 0x010400u,
v1_5 = 0x010500u,
v1_6 = 0x010600u,
};
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.
};
// Supported optimization levels.
enum class OptimizationLevel {
Zero, // No optimization.
Size, // Optimization towards reducing code size.
Performance, // Optimization towards better performance.
};
// Resource limits. These map to the "max*" fields in
// glslang::TBuiltInResource.
enum class Limit {
#define RESOURCE(NAME, FIELD, CNAME) NAME,
#include "resources.inc"
#undef RESOURCE
};
// Types of uniform variables.
enum class UniformKind {
// Image, and image buffer.
Image = 0,
// Pure sampler.
Sampler = 1,
// Sampled texture in GLSL.
// Shader Resource View, for HLSL. (Read-only image or storage buffer.)
Texture = 2,
// Uniform Buffer Object, or UBO, in GLSL.
// Also a Cbuffer in HLSL.
Buffer = 3,
// Shader Storage Buffer Object, or SSBO
StorageBuffer = 4,
// Uniform Access View, in HLSL. (Writable storage image or storage
// buffer.)
UnorderedAccessView = 5,
};
enum { kNumUniformKinds = int(UniformKind::UnorderedAccessView) + 1 };
// Shader pipeline stage.
// TODO(dneto): Replaces interface uses of EShLanguage with this enum.
enum class Stage {
Vertex,
TessEval,
TessControl,
Geometry,
Fragment,
Compute,
RayGenNV,
IntersectNV,
AnyHitNV,
ClosestHitNV,
MissNV,
CallableNV,
TaskNV,
MeshNV,
StageEnd,
};
enum { kNumStages = int(Stage::StageEnd) };
// Returns a std::array of all the Stage values.
const std::array<Stage, kNumStages>& stages() const {
static std::array<Stage, kNumStages> values{{
Stage::Vertex,
Stage::TessEval,
Stage::TessControl,
Stage::Geometry,
Stage::Fragment,
Stage::Compute,
Stage::RayGenNV,
Stage::IntersectNV,
Stage::AnyHitNV,
Stage::ClosestHitNV,
Stage::MissNV,
Stage::CallableNV,
Stage::TaskNV,
Stage::MeshNV,
}};
return values;
}
// Creates an default compiler instance targeting at Vulkan environment. Uses
// version 110 and no profile specification as the default for GLSL.
Compiler()
// The default version for glsl is 110, or 100 if you are using an es
// profile. But we want to default to a non-es profile.
: default_version_(110),
default_profile_(ENoProfile),
force_version_profile_(false),
warnings_as_errors_(false),
suppress_warnings_(false),
generate_debug_info_(false),
emit_non_semantic_debug_info_(false),
enabled_opt_passes_(),
target_env_(TargetEnv::Vulkan),
target_env_version_(TargetEnvVersion::Default),
target_spirv_version_(SpirvVersion::v1_0),
target_spirv_version_is_forced_(false),
source_language_(SourceLanguage::GLSL),
limits_(kDefaultTBuiltInResource),
auto_bind_uniforms_(false),
auto_combined_image_sampler_(false),
auto_binding_base_(),
auto_map_locations_(false),
preserve_bindings_(false),
hlsl_iomap_(false),
hlsl_offsets_(false),
hlsl_legalization_enabled_(true),
hlsl_functionality1_enabled_(false),
hlsl_16bit_types_enabled_(false),
invert_y_enabled_(false),
nan_clamp_(false),
hlsl_explicit_bindings_() {}
// Requests that the compiler place debug information into the object code,
// such as identifier names and line numbers.
void SetGenerateDebugInfo();
// Requests that the compiler emit non-semantic debug information.
// Requires VK_KHR_shader_non_semantic_info.
void SetEmitNonSemanticDebugInfo();
// Sets the optimization level to the given level. Only the last one takes
// effect if multiple calls of this method exist.
void SetOptimizationLevel(OptimizationLevel level);
// Enables or disables HLSL legalization passes.
void EnableHlslLegalization(bool hlsl_legalization_enabled);
// Enables or disables extension SPV_GOOGLE_hlsl_functionality1
void EnableHlslFunctionality1(bool enable);
// Enables or disables HLSL 16-bit types.
void EnableHlsl16BitTypes(bool enable);
// Enables or disables relaxed Vulkan rules.
//
// This allows most OpenGL shaders to compile under Vulkan semantics.
void SetVulkanRulesRelaxed(bool enable);
// Enables or disables invert position.Y output in vertex shader.
void EnableInvertY(bool enable);
// Sets whether the compiler generates code for max and min builtins which,
// if given a NaN operand, will return the other operand. Also, the clamp
// builtin will favour the non-NaN operands, as if clamp were implemented
// as a composition of max and min.
void SetNanClamp(bool enable);
// When a warning is encountered it treat it as an error.
void SetWarningsAsErrors();
// Any warning message generated is suppressed before it is output.
void SetSuppressWarnings();
// Adds an implicit macro definition obeyed by subsequent CompileShader()
// calls. The macro and definition should be passed in with their char*
// pointer and their lengths. They can be modified or deleted after this
// function has returned.
void AddMacroDefinition(const char* macro, size_t macro_length,
const char* definition, size_t definition_length);
// Sets the target environment, including version. The version value should
// be 0 or one of the values from TargetEnvVersion. The default value maps
// to Vulkan 1.0 if the target environment is Vulkan, and it maps to OpenGL
// 4.5 if the target environment is OpenGL.
void SetTargetEnv(TargetEnv env,
TargetEnvVersion version = TargetEnvVersion::Default);
// Sets the target version of SPIR-V. The module will use this version
// of SPIR-V. Defaults to the highest version of SPIR-V required to be
// supported by the target environment. E.g. default to SPIR-V 1.0 for
// Vulkan 1.0, and SPIR-V 1.3 for Vulkan 1.1.
void SetTargetSpirv(SpirvVersion version);
// Sets the souce language.
void SetSourceLanguage(SourceLanguage lang);
// Forces (without any verification) the default version and profile for
// subsequent CompileShader() calls.
void SetForcedVersionProfile(int version, EProfile profile);
// Sets a resource limit.
void SetLimit(Limit limit, int value);
// Returns the current limit.
int GetLimit(Limit limit) const;
// Set whether the compiler automatically assigns bindings to
// uniform variables that don't have explicit bindings.
void SetAutoBindUniforms(bool auto_bind) { auto_bind_uniforms_ = auto_bind; }
// Sets whether the compiler should automatically remove sampler variables
// and convert image variables to combined image-sampler variables.
void SetAutoCombinedImageSampler(bool auto_combine) {
auto_combined_image_sampler_ = auto_combine;
}
// Sets the lowest binding number used when automatically assigning bindings
// for uniform resources of the given type, for all shader stages. The default
// base is zero.
void SetAutoBindingBase(UniformKind kind, uint32_t base) {
for (auto stage : stages()) {
SetAutoBindingBaseForStage(stage, kind, base);
}
}
// Sets the lowest binding number used when automatically assigning bindings
// for uniform resources of the given type for a specific shader stage. The
// default base is zero.
void SetAutoBindingBaseForStage(Stage stage, UniformKind kind,
uint32_t base) {
auto_binding_base_[static_cast<int>(stage)][static_cast<int>(kind)] = base;
}
// Sets whether the compiler should preserve all bindings, even when those
// bindings are not used.
void SetPreserveBindings(bool preserve_bindings) {
preserve_bindings_ = preserve_bindings;
}
// Sets whether the compiler automatically assigns locations to
// uniform variables that don't have explicit locations.
void SetAutoMapLocations(bool auto_map) { auto_map_locations_ = auto_map; }
// Use HLSL IO mapping rules for bindings. Default is false.
void SetHlslIoMapping(bool hlsl_iomap) { hlsl_iomap_ = hlsl_iomap; }
// Use HLSL rules for offsets in "transparent" memory. These allow for
// tighter packing of some combinations of types than standard GLSL packings.
void SetHlslOffsets(bool hlsl_offsets) { hlsl_offsets_ = hlsl_offsets; }
// Sets an explicit set and binding for the given HLSL register.
void SetHlslRegisterSetAndBinding(const std::string& reg,
const std::string& set,
const std::string& binding) {
for (auto stage : stages()) {
SetHlslRegisterSetAndBindingForStage(stage, reg, set, binding);
}
}
// Sets an explicit set and binding for the given HLSL register in the given
// shader stage. For example,
// SetHlslRegisterSetAndBinding(Stage::Fragment, "t1", "4", "5")
// means register "t1" in a fragment shader should map to binding 5 in set 4.
// (Glslang wants this data as strings, not ints or enums.) The string data is
// copied.
void SetHlslRegisterSetAndBindingForStage(Stage stage, const std::string& reg,
const std::string& set,
const std::string& binding) {
hlsl_explicit_bindings_[static_cast<int>(stage)].push_back(reg);
hlsl_explicit_bindings_[static_cast<int>(stage)].push_back(set);
hlsl_explicit_bindings_[static_cast<int>(stage)].push_back(binding);
}
// Compiles the shader source in the input_source_string parameter.
//
// If the forced_shader stage parameter is not EShLangCount then
// the shader is assumed to be of the given stage.
//
// For HLSL compilation, entry_point_name is the null-terminated string for
// the entry point. For GLSL compilation, entry_point_name is ignored, and
// compilation assumes the entry point is named "main".
//
// The stage_callback function will be called if a shader_stage has
// not been forced and the stage can not be determined
// from the shader text. Any #include directives are parsed with the given
// includer.
//
// The initializer parameter must be a valid GlslangInitializer object.
// Acquire will be called on the initializer and the result will be
// destroyed before the function ends.
//
// The output_type parameter determines what kind of output should be
// produced.
//
// Any error messages are written as if the file name were error_tag.
// Any errors are written to the error_stream parameter.
// total_warnings and total_errors are incremented once for every
// warning or error encountered respectively.
//
// Returns a tuple consisting of three fields. 1) a boolean which is true when
// the compilation succeeded, and false otherwise; 2) a vector of 32-bit words
// which contains the compilation output data, either compiled SPIR-V binary
// code, or the text string generated in preprocessing-only or disassembly
// mode; 3) the size of the output data in bytes. When the output is SPIR-V
// binary code, the size is the number of bytes of valid data in the vector.
// If the output is a text string, the size equals the length of that string.
std::tuple<bool, std::vector<uint32_t>, size_t> Compile(
const string_piece& input_source_string, EShLanguage forced_shader_stage,
const std::string& error_tag, const char* entry_point_name,
const std::function<EShLanguage(std::ostream* error_stream,
const string_piece& error_tag)>&
stage_callback,
CountingIncluder& includer, OutputType output_type,
std::ostream* error_stream, size_t* total_warnings, size_t* total_errors) const;
static EShMessages GetDefaultRules() {
return static_cast<EShMessages>(EShMsgSpvRules | EShMsgVulkanRules |
EShMsgCascadingErrors);
}
protected:
// Preprocesses a shader whose filename is filename and content is
// shader_source. If preprocessing is successful, returns true, the
// preprocessed shader, and any warning message as a tuple. Otherwise,
// returns false, an empty string, and error messages as a tuple.
//
// The error_tag parameter is the name to use for outputting errors.
// The shader_source parameter is the input shader's source text.
// The shader_preamble parameter is a context-specific preamble internally
// prepended to shader_text without affecting the validity of its #version
// position.
//
// Any #include directives are processed with the given includer.
//
// If force_version_profile_ is set, the shader's version/profile is forced
// to be default_version_/default_profile_ regardless of the #version
// directive in the source code.
std::tuple<bool, std::string, std::string> PreprocessShader(
const std::string& error_tag, const string_piece& shader_source,
const string_piece& shader_preamble, CountingIncluder& includer) const;
// Cleans up the preamble in a given preprocessed shader.
//
// The error_tag parameter is the name to be given for the main file.
// The pound_extension parameter is the #extension directive we prepended to
// the original shader source code via preamble.
// The num_include_directives parameter is the number of #include directives
// appearing in the original shader source code.
// The is_for_next_line means whether the #line sets the line number for the
// next line.
//
// If no #include directive is used in the shader source code, we can safely
// delete the #extension directive we injected via preamble. Otherwise, we
// need to adjust it if there exists a #version directive in the original
// shader source code.
std::string CleanupPreamble(const string_piece& preprocessed_shader,
const string_piece& error_tag,
const string_piece& pound_extension,
int num_include_directives,
bool is_for_next_line) const;
// Determines version and profile from command line, or the source code.
// Returns the decoded version and profile pair on success. Otherwise,
// returns (0, ENoProfile).
std::pair<int, EProfile> DeduceVersionProfile(
const std::string& preprocessed_shader) const;
// Determines the shader stage from pragmas embedded in the source text if
// possible. In the returned pair, the glslang EShLanguage is the shader
// stage deduced. If no #pragma directives for shader stage exist, it's
// EShLangCount. If errors occur, the second element in the pair is the
// error message. Otherwise, it's an empty string.
std::pair<EShLanguage, std::string> GetShaderStageFromSourceCode(
string_piece filename, const std::string& preprocessed_shader) const;
// Determines version and profile from command line, or the source code.
// Returns the decoded version and profile pair on success. Otherwise,
// returns (0, ENoProfile).
std::pair<int, EProfile> DeduceVersionProfile(
const std::string& preprocessed_shader);
// Gets version and profile specification from the given preprocessedshader.
// Returns the decoded version and profile pair on success. Otherwise,
// returns (0, ENoProfile).
std::pair<int, EProfile> GetVersionProfileFromSourceCode(
const std::string& preprocessed_shader) const;
// Version to use when force_version_profile_ is true.
int default_version_;
// Profile to use when force_version_profile_ is true.
EProfile default_profile_;
// When true, use the default version and profile from eponymous data members.
bool force_version_profile_;
// Macro definitions that must be available to reference in the shader source.
MacroDictionary predefined_macros_;
// When true, treat warnings as errors.
bool warnings_as_errors_;
// Supress warnings when true.
bool suppress_warnings_;
// When true, compilation will generate debug info with the binary SPIR-V
// output.
bool generate_debug_info_;
// When true and generate_debug_info_ is also set, generate non-semantic debug
// information.
bool emit_non_semantic_debug_info_;
// Optimization passes to be applied.
std::vector<PassId> enabled_opt_passes_;
// The target environment to compile with. This controls the glslang
// EshMessages bitmask, which determines which dialect of GLSL and which
// SPIR-V codegen semantics are used. This impacts the warning & error
// messages as well as the set of available builtins, as per the
// implementation of glslang.
TargetEnv target_env_;
// The version number of the target environment. The numbering scheme is
// particular to each target environment. If this is 0, then use a default
// for that particular target environment. See libshaders/shaderc/shaderc.h
// for those defaults.
TargetEnvVersion target_env_version_;
// The SPIR-V version to be used for the generated module. Defaults to 1.0.
SpirvVersion target_spirv_version_;
// True if the user explicitly set the target SPIR-V version.
bool target_spirv_version_is_forced_;
// The source language. Defaults to GLSL.
SourceLanguage source_language_;
// The resource limits to be used.
TBuiltInResource limits_;
// True if the compiler should automatically bind uniforms that don't
// have explicit bindings.
bool auto_bind_uniforms_;
// True if the compiler should automatically remove sampler variables
// and convert image variables to combined image-sampler variables.
bool auto_combined_image_sampler_;
// The base binding number per uniform type, per stage, used when automatically
// binding uniforms that don't hzve explicit bindings in the shader source.
// The default is zero.
uint32_t auto_binding_base_[kNumStages][kNumUniformKinds];
// True if the compiler should automatically map uniforms that don't
// have explicit locations.
bool auto_map_locations_;
// True if the compiler should preserve all bindings, even when unused.
bool preserve_bindings_;
// True if the compiler should use HLSL IO mapping rules when compiling HLSL.
bool hlsl_iomap_;
// True if the compiler should determine block member offsets using HLSL
// packing rules instead of standard GLSL rules.
bool hlsl_offsets_;
// True if the compiler should perform legalization optimization passes if
// source language is HLSL.
bool hlsl_legalization_enabled_;
// True if the compiler should support extension SPV_GOOGLE_hlsl_functionality1.
bool hlsl_functionality1_enabled_;
// True if the compiler should support 16-bit HLSL types.
bool hlsl_16bit_types_enabled_;
// True if the compiler should relax Vulkan rules to allow OGL shaders to
// compile.
bool vulkan_rules_relaxed_ = false;
// True if the compiler should invert position.Y output in vertex shader.
bool invert_y_enabled_;
// True if the compiler generates code for max and min builtins which,
// if given a NaN operand, will return the other operand. Also, the clamp
// builtin will favour the non-NaN operands, as if clamp were implemented
// as a composition of max and min.
bool nan_clamp_;
// A sequence of triples, each triple representing a specific HLSL register
// name, and the set and binding numbers it should be mapped to, but in
// the form of strings. This is how Glslang wants to consume the data.
std::vector<std::string> hlsl_explicit_bindings_[kNumStages];
};
// Converts a string to a vector of uint32_t by copying the content of a given
// string to the vector and returns it. Appends '\0' at the end if extra bytes
// are required to complete the last element.
std::vector<uint32_t> ConvertStringToVector(const std::string& str);
// Converts a valid Glslang shader stage value to a Compiler::Stage value.
inline Compiler::Stage ConvertToStage(EShLanguage stage) {
switch (stage) {
case EShLangVertex:
return Compiler::Stage::Vertex;
case EShLangTessControl:
return Compiler::Stage::TessEval;
case EShLangTessEvaluation:
return Compiler::Stage::TessControl;
case EShLangGeometry:
return Compiler::Stage::Geometry;
case EShLangFragment:
return Compiler::Stage::Fragment;
case EShLangCompute:
return Compiler::Stage::Compute;
case EShLangRayGenNV:
return Compiler::Stage::RayGenNV;
case EShLangIntersectNV:
return Compiler::Stage::IntersectNV;
case EShLangAnyHitNV:
return Compiler::Stage::AnyHitNV;
case EShLangClosestHitNV:
return Compiler::Stage::ClosestHitNV;
case EShLangMissNV:
return Compiler::Stage::MissNV;
case EShLangCallableNV:
return Compiler::Stage::CallableNV;
case EShLangTaskNV:
return Compiler::Stage::TaskNV;
case EShLangMeshNV:
return Compiler::Stage::MeshNV;
default:
break;
}
assert(false && "Invalid case");
return Compiler::Stage::Compute;
}
// A GlslangClientInfo captures target client version and desired SPIR-V
// version.
struct GlslangClientInfo {
GlslangClientInfo() {}
GlslangClientInfo(const std::string& e, glslang::EShClient c,
glslang::EShTargetClientVersion cv,
glslang::EShTargetLanguage l,
glslang::EShTargetLanguageVersion lv)
: error(e),
client(c),
client_version(cv),
target_language(l),
target_language_version(lv) {}
std::string error; // Empty if ok, otherwise contains the error message.
glslang::EShClient client = glslang::EShClientNone;
glslang::EShTargetClientVersion client_version;
glslang::EShTargetLanguage target_language = glslang::EShTargetSpv;
glslang::EShTargetLanguageVersion target_language_version =
glslang::EShTargetSpv_1_0;
};
// Returns the mappings to Glslang client, client version, and SPIR-V version.
// Also indicates whether the input values were valid.
GlslangClientInfo GetGlslangClientInfo(
const std::string& error_tag, // Indicates source location, for errors.
shaderc_util::Compiler::TargetEnv env,
shaderc_util::Compiler::TargetEnvVersion env_version,
shaderc_util::Compiler::SpirvVersion spv_version,
bool spv_version_is_forced);
} // namespace shaderc_util
#endif // LIBSHADERC_UTIL_INC_COMPILER_H

View File

@@ -0,0 +1,101 @@
// 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 LIBSHADERC_UTIL_COUNTING_INCLUDER_H
#define LIBSHADERC_UTIL_COUNTING_INCLUDER_H
#include <atomic>
#include "glslang/Public/ShaderLang.h"
#include "libshaderc_util/mutex.h"
namespace shaderc_util {
// An Includer that counts how many #include directives it saw.
// Inclusions are internally serialized, but releasing a previous result
// can occur concurrently.
class CountingIncluder : public glslang::TShader::Includer {
public:
// Done as .store(0) instead of in the initializer list for the following
// reasons:
// Clang > 3.6 will complain about it if it is written as ({0}).
// VS2013 fails if it is written as {0}.
// G++-4.8 does not correctly support std::atomic_init.
CountingIncluder() {
num_include_directives_.store(0);
}
enum class IncludeType {
System, // Only do < > include search
Local, // Only do " " include search
};
// Resolves an include request for a source by name, type, and name of the
// requesting source. For the semantics of the result, see the base class.
// Also increments num_include_directives and returns the results of
// include_delegate(filename). Subclasses should override include_delegate()
// instead of this method. Inclusions are serialized.
glslang::TShader::Includer::IncludeResult* includeSystem(
const char* requested_source, const char* requesting_source,
size_t include_depth) final {
++num_include_directives_;
include_mutex_.lock();
auto result = include_delegate(requested_source, requesting_source,
IncludeType::System, include_depth);
include_mutex_.unlock();
return result;
}
// Like includeSystem, but for "local" include search.
glslang::TShader::Includer::IncludeResult* includeLocal(
const char* requested_source, const char* requesting_source,
size_t include_depth) final {
++num_include_directives_;
include_mutex_.lock();
auto result = include_delegate(requested_source, requesting_source,
IncludeType::Local, include_depth);
include_mutex_.unlock();
return result;
}
// Releases the given IncludeResult.
void releaseInclude(glslang::TShader::Includer::IncludeResult* result) final {
release_delegate(result);
}
int num_include_directives() const { return num_include_directives_.load(); }
private:
// Invoked by this class to provide results to
// glslang::TShader::Includer::include.
virtual glslang::TShader::Includer::IncludeResult* include_delegate(
const char* requested_source, const char* requesting_source,
IncludeType type, size_t include_depth) = 0;
// Release the given IncludeResult.
virtual void release_delegate(
glslang::TShader::Includer::IncludeResult* result) = 0;
// The number of #include directive encountered.
std::atomic_int num_include_directives_;
// A mutex to protect against concurrent inclusions. We can't trust
// our delegates to be safe for concurrent inclusions.
shaderc_util::mutex include_mutex_;
};
}
#endif // LIBSHADERC_UTIL_COUNTING_INCLUDER_H

View File

@@ -0,0 +1,26 @@
// Copyright 2018 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 LIBSHADERC_UTIL_EXCEPTIONS_H_
#define LIBSHADERC_UTIL_EXCEPTIONS_H_
#if (defined(_MSC_VER) && !defined(_CPPUNWIND)) || !defined(__EXCEPTIONS)
#define TRY_IF_EXCEPTIONS_ENABLED
#define CATCH_IF_EXCEPTIONS_ENABLED(X) if (0)
#else
#define TRY_IF_EXCEPTIONS_ENABLED try
#define CATCH_IF_EXCEPTIONS_ENABLED(X) catch (X)
#endif
#endif // LIBSHADERC_UTIL_EXCEPTIONS_H_

View File

@@ -0,0 +1,57 @@
// 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 LIBSHADERC_UTIL_SRC_FILE_FINDER_H_
#define LIBSHADERC_UTIL_SRC_FILE_FINDER_H_
#include <string>
#include <vector>
namespace shaderc_util {
// Finds files within a search path.
class FileFinder {
public:
// Searches for a read-openable file based on filename, which must be
// non-empty. The search is attempted on filename prefixed by each element of
// search_path() in turn. The first hit is returned, or an empty string if
// there are no hits. Search attempts treat their argument the way
// std::fopen() treats its filename argument, ignoring whether the path is
// absolute or relative.
//
// If a search_path() element is non-empty and not ending in a slash, then a
// slash is inserted between it and filename before its search attempt. An
// empty string in search_path() means that the filename is tried as-is.
std::string FindReadableFilepath(const std::string& filename) const;
// Searches for a read-openable file based on filename, which must be
// non-empty. The search is first attempted as a path relative to
// the requesting_file parameter. If no file is found relative to the
// requesting_file then this acts as FindReadableFilepath does. If
// requesting_file does not contain a '/' or a '\' character then it is
// assumed to be a filename and the request will be relative to the
// current directory.
std::string FindRelativeReadableFilepath(const std::string& requesting_file,
const std::string& filename) const;
// Search path for Find(). Users may add/remove elements as desired.
std::vector<std::string>& search_path() { return search_path_; }
private:
std::vector<std::string> search_path_;
};
} // namespace shaderc_util
#endif // LIBSHADERC_UTIL_SRC_FILE_FINDER_H_

View File

@@ -0,0 +1,36 @@
// 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 LIBSHADERC_UTIL_FORMAT_H_
#define LIBSHADERC_UTIL_FORMAT_H_
#include <sstream>
namespace shaderc_util {
// Returns a string containing <prefix><key><infix><value><postfix> for every
// key-value entry in map.
template <typename Map>
std::string format(const Map& map, const std::string& prefix,
const std::string& infix, const std::string& postfix) {
std::stringstream s;
for (const auto& pair : map) {
s << prefix << pair.first << infix << pair.second << postfix;
}
return s.str();
}
} // namespace shaderc_util
#endif // LIBSHADERC_UTIL_FORMAT_H_

View File

@@ -0,0 +1,69 @@
// 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 LIBSHADERC_UTIL_IO_H_
#define LIBSHADERC_UTIL_IO_H_
#include <string>
#include <vector>
#include "string_piece.h"
namespace shaderc_util {
// Returns true if the given path is an absolute path.
bool IsAbsolutePath(const std::string& path);
// A helper function to return the base file name from either absolute path or
// relative path representation of a file. It keeps the component from the last
// '/' or '\' to the end of the given string. If the component is '..' or '.',
// returns an empty string. If '/' or '\' is the last char of the given string,
// also returns an empty string.
// e.g.: dir_a/dir_b/file_c.vert => file_c.vert
// dir_a/dir_b/.. => <empty string>
// dir_a/dir_b/. => <empty string>
// dir_a/dirb/c/ => <empty string>
// Note that this method doesn't check whether the given path is a valid one or
// not.
std::string GetBaseFileName(const std::string& file_path);
// Reads all of the characters in a given file into input_data. Outputs an
// error message to std::cerr if the file could not be read and returns false if
// there was an error. If the input_file is "-", then input is read from
// std::cin.
bool ReadFile(const std::string& input_file_name,
std::vector<char>* input_data);
// Returns and initializes the file_stream parameter if the output_filename
// refers to a file, or returns &std::cout if the output_filename is "-".
// Returns nullptr and emits an error message to err if the file could
// not be opened for writing. If the output refers to a file, and the open
// failed for writing, file_stream is left with its fail_bit set.
std::ostream* GetOutputStream(const string_piece& output_filename,
std::ofstream* file_stream, std::ostream* err);
// Writes output_data to a file, overwriting if it exists. If output_file_name
// is "-", writes to std::cout.
bool WriteFile(std::ostream* output_stream, const string_piece& output_data);
// Flush the standard output stream and set it to binary mode. Subsequent
// output will not translate newlines to carriage-return newline pairs.
void FlushAndSetBinaryModeOnStdout();
// Flush the standard output stream and set it to text mode. Subsequent
// output will translate newlines to carriage-return newline pairs.
void FlushAndSetTextModeOnStdout();
} // namespace shaderc_util
#endif // LIBSHADERC_UTIL_IO_H_

View File

@@ -0,0 +1,86 @@
// 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 LIBSHADERC_UTIL_SRC_MESSAGE_H_
#define LIBSHADERC_UTIL_SRC_MESSAGE_H_
#include "libshaderc_util/string_piece.h"
namespace shaderc_util {
// TODO(antiagainst): document the differences of the following message types.
enum class MessageType {
Warning,
Error,
ErrorSummary,
WarningSummary,
GlobalWarning,
GlobalError,
Unknown,
Ignored
};
// Given a glslang warning/error message, processes it in the following way and
// returns its message type.
//
// * Places the source name into the source_name parameter, if found.
// Otherwise, clears the source_name parameter.
// * Places the line number into the line_number parameter, if found.
// Otherwise, clears the line_number parameter.
// * Places the rest of the message (the text past warning/error prefix, source
// name, and line number) into the rest parameter.
//
// If warnings_as_errors is set to true, then all warnings will be treated as
// errors.
// If suppress_warnings is set to true, then no warnings will be emitted. This
// takes precedence over warnings_as_errors.
//
// Examples:
// "ERROR: 0:2: Message"
// source_name="0", line_number="2", rest="Message"
// "Warning, Message"
// source_name="", line_number="", rest="Message"
// "ERROR: 2 errors found."
// source_name="2", line_number="", rest="errors found".
//
// Note that filenames can contain colons:
// "ERROR: foo:bar.comp.hlsl:2: 'a' : unknown variable"
MessageType ParseGlslangOutput(const shaderc_util::string_piece& message,
bool warnings_as_errors, bool suppress_warnings,
shaderc_util::string_piece* source_name,
shaderc_util::string_piece* line_number,
shaderc_util::string_piece* rest);
// Filters error_messages received from glslang, and outputs, to error_stream,
// any that are not ignored in a clang like format. If the warnings_as_errors
// boolean is set, then all warnings will be treated as errors. If the
// suppress_warnings boolean is set then any warning messages are ignored. This
// takes precedence over warnings_as_errors. Increments total_warnings and
// total_errors based on the message types.
// Returns true if no new errors were found when parsing the messages.
// "<command line>" will substitute "-1" appearing at the string name/number
// segment.
bool PrintFilteredErrors(const shaderc_util::string_piece& file_name,
std::ostream* error_stream, bool warnings_as_errors,
bool suppress_warnings, const char* error_list,
size_t* total_warnings, size_t* total_errors);
// Outputs, to error_stream, the number of warnings and errors if there are
// any.
void OutputMessages(std::ostream* error_stream, size_t total_warnings,
size_t total_errors);
} // namespace glslc
#endif // LIBSHADERC_UTIL_SRC_MESSAGE_H_

View File

@@ -0,0 +1,107 @@
// 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 LIBSHADERC_UTIL_INC_MUTEX_H
#define LIBSHADERC_UTIL_INC_MUTEX_H
// shaderc_util::mutex will be defined and specialized
// depending on the platform that is being compiled.
// It is more or less conformant to the C++11 specification of std::mutex.
// However it does not implement try_lock.
#ifdef _WIN32
// windows.h #defines min and max if we don't define this.
// this means things like std::min and std::max break
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
namespace shaderc_util {
// As the name suggests, this mutex class is for running on windows.
// It conforms to the c++11 mutex implementation, and should be a
// drop in replacement.
class windows_mutex {
public:
using native_handle_type = HANDLE;
windows_mutex() { mutex_ = CreateMutex(nullptr, false, nullptr); }
~windows_mutex() {
if (mutex_ != INVALID_HANDLE_VALUE) {
CloseHandle(mutex_);
}
}
windows_mutex(const windows_mutex&) = delete;
windows_mutex& operator=(const windows_mutex&) = delete;
// Locks this mutex, waiting until the mutex is unlocked if it is not already.
// It is not valid to lock a mutex that has already been locked.
void lock() { WaitForSingleObject(mutex_, INFINITE); }
// Unlocks this mutex. It is invalid to unlock a mutex that this thread
// has not already locked.
void unlock() { ReleaseMutex(mutex_); }
// Returns the native handle for this mutex. In this case a HANDLE object.
native_handle_type native_handle() { return mutex_; }
private:
HANDLE mutex_;
};
using mutex = windows_mutex;
}
#else
#include <pthread.h>
#include <memory>
namespace shaderc_util {
// As the name suggests, this mutex class is for running with pthreads.
// It conforms to the c++11 mutex implementation, and should be a
// drop in replacement.
class posix_mutex {
public:
using native_handle_type = pthread_mutex_t*;
posix_mutex() { pthread_mutex_init(&mutex_, nullptr); }
~posix_mutex() { pthread_mutex_destroy(&mutex_); }
posix_mutex(const posix_mutex&) = delete;
posix_mutex& operator=(const posix_mutex&) = delete;
// Locks this mutex, waiting until the mutex is unlocked if it is not already.
// It is not valid to lock a mutex that has already been locked.
void lock() { pthread_mutex_lock(&mutex_); }
// Unlocks this mutex. It is invalid to unlock a mutex that this thread
// has not already locked.
void unlock() { pthread_mutex_unlock(&mutex_); }
// Returns the native handle for this mutex. In this case a pthread_mutex_t*.
native_handle_type native_handle() { return &mutex_; }
private:
pthread_mutex_t mutex_;
};
using mutex = posix_mutex;
}
#endif
#endif // LIBSHADERC_UTIL_INC_MUTEX_H

View File

@@ -0,0 +1,30 @@
// 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 LIBSHADERC_UTIL_RESOURCES_H_
#define LIBSHADERC_UTIL_RESOURCES_H_
// We want TBuiltInResource
#include "glslang/Include/ResourceLimits.h"
namespace shaderc_util {
using TBuiltInResource = ::TBuiltInResource;
// A set of suitable defaults.
extern const TBuiltInResource kDefaultTBuiltInResource;
} // namespace shaderc_util
#endif // LIBSHADERC_UTIL_RESOURCES_H_

View File

@@ -0,0 +1,143 @@
// 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.
// These are the resource limits in a glslang::TBuiltInResource.
// The first field is the string name to be used in a configuration setting.
// The second field is the fieldname in TBuiltInResource.
// The third field is the enum name fragment for shaderc_limit.
//
// TODO(dneto): Consider using a single list of names, but use a Python script
// to generate *this* file. The original data file would have the first field,
// then generate the second field by lowering the case of the first letter, and
// generate the third field by taking the second field, and converting a
// lower-to-upper case transition into an underscore with lower-case.
RESOURCE(MaxLights,maxLights,max_lights)
RESOURCE(MaxClipPlanes,maxClipPlanes,max_clip_planes)
RESOURCE(MaxTextureUnits,maxTextureUnits,max_texture_units)
RESOURCE(MaxTextureCoords,maxTextureCoords,max_texture_coords)
RESOURCE(MaxVertexAttribs,maxVertexAttribs,max_vertex_attribs)
RESOURCE(MaxVertexUniformComponents,maxVertexUniformComponents,max_vertex_uniform_components)
RESOURCE(MaxVaryingFloats,maxVaryingFloats,max_varying_floats)
RESOURCE(MaxVertexTextureImageUnits,maxVertexTextureImageUnits,max_vertex_texture_image_units)
RESOURCE(MaxCombinedTextureImageUnits,maxCombinedTextureImageUnits,max_combined_texture_image_units)
RESOURCE(MaxTextureImageUnits,maxTextureImageUnits,max_texture_image_units)
RESOURCE(MaxFragmentUniformComponents,maxFragmentUniformComponents,max_fragment_uniform_components)
RESOURCE(MaxDrawBuffers,maxDrawBuffers,max_draw_buffers)
RESOURCE(MaxVertexUniformVectors,maxVertexUniformVectors,max_vertex_uniform_vectors)
RESOURCE(MaxVaryingVectors,maxVaryingVectors,max_varying_vectors)
RESOURCE(MaxFragmentUniformVectors,maxFragmentUniformVectors,max_fragment_uniform_vectors)
RESOURCE(MaxVertexOutputVectors,maxVertexOutputVectors,max_vertex_output_vectors)
RESOURCE(MaxFragmentInputVectors,maxFragmentInputVectors,max_fragment_input_vectors)
RESOURCE(MinProgramTexelOffset,minProgramTexelOffset,min_program_texel_offset)
RESOURCE(MaxProgramTexelOffset,maxProgramTexelOffset,max_program_texel_offset)
RESOURCE(MaxClipDistances,maxClipDistances,max_clip_distances)
RESOURCE(MaxComputeWorkGroupCountX,maxComputeWorkGroupCountX,max_compute_work_group_count_x)
RESOURCE(MaxComputeWorkGroupCountY,maxComputeWorkGroupCountY,max_compute_work_group_count_y)
RESOURCE(MaxComputeWorkGroupCountZ,maxComputeWorkGroupCountZ,max_compute_work_group_count_z)
RESOURCE(MaxComputeWorkGroupSizeX,maxComputeWorkGroupSizeX,max_compute_work_group_size_x)
RESOURCE(MaxComputeWorkGroupSizeY,maxComputeWorkGroupSizeY,max_compute_work_group_size_y)
RESOURCE(MaxComputeWorkGroupSizeZ,maxComputeWorkGroupSizeZ,max_compute_work_group_size_z)
RESOURCE(MaxComputeUniformComponents,maxComputeUniformComponents,max_compute_uniform_components)
RESOURCE(MaxComputeTextureImageUnits,maxComputeTextureImageUnits,max_compute_texture_image_units)
RESOURCE(MaxComputeImageUniforms,maxComputeImageUniforms,max_compute_image_uniforms)
RESOURCE(MaxComputeAtomicCounters,maxComputeAtomicCounters,max_compute_atomic_counters)
RESOURCE(MaxComputeAtomicCounterBuffers,maxComputeAtomicCounterBuffers,max_compute_atomic_counter_buffers)
RESOURCE(MaxVaryingComponents,maxVaryingComponents,max_varying_components)
RESOURCE(MaxVertexOutputComponents,maxVertexOutputComponents,max_vertex_output_components)
RESOURCE(MaxGeometryInputComponents,maxGeometryInputComponents,max_geometry_input_components)
RESOURCE(MaxGeometryOutputComponents,maxGeometryOutputComponents,max_geometry_output_components)
RESOURCE(MaxFragmentInputComponents,maxFragmentInputComponents,max_fragment_input_components)
RESOURCE(MaxImageUnits,maxImageUnits,max_image_units)
RESOURCE(MaxCombinedImageUnitsAndFragmentOutputs,maxCombinedImageUnitsAndFragmentOutputs,max_combined_image_units_and_fragment_outputs)
RESOURCE(MaxCombinedShaderOutputResources,maxCombinedShaderOutputResources,max_combined_shader_output_resources)
RESOURCE(MaxImageSamples,maxImageSamples,max_image_samples)
RESOURCE(MaxVertexImageUniforms,maxVertexImageUniforms,max_vertex_image_uniforms)
RESOURCE(MaxTessControlImageUniforms,maxTessControlImageUniforms,max_tess_control_image_uniforms)
RESOURCE(MaxTessEvaluationImageUniforms,maxTessEvaluationImageUniforms,max_tess_evaluation_image_uniforms)
RESOURCE(MaxGeometryImageUniforms,maxGeometryImageUniforms,max_geometry_image_uniforms)
RESOURCE(MaxFragmentImageUniforms,maxFragmentImageUniforms,max_fragment_image_uniforms)
RESOURCE(MaxCombinedImageUniforms,maxCombinedImageUniforms,max_combined_image_uniforms)
RESOURCE(MaxGeometryTextureImageUnits,maxGeometryTextureImageUnits,max_geometry_texture_image_units)
RESOURCE(MaxGeometryOutputVertices,maxGeometryOutputVertices,max_geometry_output_vertices)
RESOURCE(MaxGeometryTotalOutputComponents,maxGeometryTotalOutputComponents,max_geometry_total_output_components)
RESOURCE(MaxGeometryUniformComponents,maxGeometryUniformComponents,max_geometry_uniform_components)
RESOURCE(MaxGeometryVaryingComponents,maxGeometryVaryingComponents,max_geometry_varying_components)
RESOURCE(MaxTessControlInputComponents,maxTessControlInputComponents,max_tess_control_input_components)
RESOURCE(MaxTessControlOutputComponents,maxTessControlOutputComponents,max_tess_control_output_components)
RESOURCE(MaxTessControlTextureImageUnits,maxTessControlTextureImageUnits,max_tess_control_texture_image_units)
RESOURCE(MaxTessControlUniformComponents,maxTessControlUniformComponents,max_tess_control_uniform_components)
RESOURCE(MaxTessControlTotalOutputComponents,maxTessControlTotalOutputComponents,max_tess_control_total_output_components)
RESOURCE(MaxTessEvaluationInputComponents,maxTessEvaluationInputComponents,max_tess_evaluation_input_components)
RESOURCE(MaxTessEvaluationOutputComponents,maxTessEvaluationOutputComponents,max_tess_evaluation_output_components)
RESOURCE(MaxTessEvaluationTextureImageUnits,maxTessEvaluationTextureImageUnits,max_tess_evaluation_texture_image_units)
RESOURCE(MaxTessEvaluationUniformComponents,maxTessEvaluationUniformComponents,max_tess_evaluation_uniform_components)
RESOURCE(MaxTessPatchComponents,maxTessPatchComponents,max_tess_patch_components)
RESOURCE(MaxPatchVertices,maxPatchVertices,max_patch_vertices)
RESOURCE(MaxTessGenLevel,maxTessGenLevel,max_tess_gen_level)
RESOURCE(MaxViewports,maxViewports,max_viewports)
RESOURCE(MaxVertexAtomicCounters,maxVertexAtomicCounters,max_vertex_atomic_counters)
RESOURCE(MaxTessControlAtomicCounters,maxTessControlAtomicCounters,max_tess_control_atomic_counters)
RESOURCE(MaxTessEvaluationAtomicCounters,maxTessEvaluationAtomicCounters,max_tess_evaluation_atomic_counters)
RESOURCE(MaxGeometryAtomicCounters,maxGeometryAtomicCounters,max_geometry_atomic_counters)
RESOURCE(MaxFragmentAtomicCounters,maxFragmentAtomicCounters,max_fragment_atomic_counters)
RESOURCE(MaxCombinedAtomicCounters,maxCombinedAtomicCounters,max_combined_atomic_counters)
RESOURCE(MaxAtomicCounterBindings,maxAtomicCounterBindings,max_atomic_counter_bindings)
RESOURCE(MaxVertexAtomicCounterBuffers,maxVertexAtomicCounterBuffers,max_vertex_atomic_counter_buffers)
RESOURCE(MaxTessControlAtomicCounterBuffers,maxTessControlAtomicCounterBuffers,max_tess_control_atomic_counter_buffers)
RESOURCE(MaxTessEvaluationAtomicCounterBuffers,maxTessEvaluationAtomicCounterBuffers,max_tess_evaluation_atomic_counter_buffers)
RESOURCE(MaxGeometryAtomicCounterBuffers,maxGeometryAtomicCounterBuffers,max_geometry_atomic_counter_buffers)
RESOURCE(MaxFragmentAtomicCounterBuffers,maxFragmentAtomicCounterBuffers,max_fragment_atomic_counter_buffers)
RESOURCE(MaxCombinedAtomicCounterBuffers,maxCombinedAtomicCounterBuffers,max_combined_atomic_counter_buffers)
RESOURCE(MaxAtomicCounterBufferSize,maxAtomicCounterBufferSize,max_atomic_counter_buffer_size)
RESOURCE(MaxTransformFeedbackBuffers,maxTransformFeedbackBuffers,max_transform_feedback_buffers)
RESOURCE(MaxTransformFeedbackInterleavedComponents,maxTransformFeedbackInterleavedComponents,max_transform_feedback_interleaved_components)
RESOURCE(MaxCullDistances,maxCullDistances,max_cull_distances)
RESOURCE(MaxCombinedClipAndCullDistances,maxCombinedClipAndCullDistances,max_combined_clip_and_cull_distances)
RESOURCE(MaxSamples,maxSamples,max_samples)
RESOURCE(MaxMeshOutputVerticesNV, maxMeshOutputVerticesNV,
max_mesh_output_vertices_nv)
RESOURCE(MaxMeshOutputPrimitivesNV, maxMeshOutputPrimitivesNV,
max_mesh_output_primitives_nv)
RESOURCE(MaxMeshWorkGroupSizeX_NV, maxMeshWorkGroupSizeX_NV,
max_mesh_work_group_size_x_nv)
RESOURCE(MaxMeshWorkGroupSizeY_NV, maxMeshWorkGroupSizeY_NV,
max_mesh_work_group_size_y_nv)
RESOURCE(MaxMeshWorkGroupSizeZ_NV, maxMeshWorkGroupSizeZ_NV,
max_mesh_work_group_size_z_nv)
RESOURCE(MaxTaskWorkGroupSizeX_NV, maxTaskWorkGroupSizeX_NV,
max_task_work_group_size_x_nv)
RESOURCE(MaxTaskWorkGroupSizeY_NV, maxTaskWorkGroupSizeY_NV,
max_task_work_group_size_y_nv)
RESOURCE(MaxTaskWorkGroupSizeZ_NV, maxTaskWorkGroupSizeZ_NV,
max_task_work_group_size_z_nv)
RESOURCE(MaxMeshViewCountNV, maxMeshViewCountNV, max_mesh_view_count_nv)
RESOURCE(MaxMeshOutputVerticesEXT, maxMeshOutputVerticesEXT,
max_mesh_output_vertices_ext)
RESOURCE(MaxMeshOutputPrimitivesEXT, maxMeshOutputPrimitivesEXT,
max_mesh_output_primitives_ext)
RESOURCE(MaxMeshWorkGroupSizeX_EXT, maxMeshWorkGroupSizeX_EXT,
max_mesh_work_group_size_x_ext)
RESOURCE(MaxMeshWorkGroupSizeY_EXT, maxMeshWorkGroupSizeY_EXT,
max_mesh_work_group_size_y_ext)
RESOURCE(MaxMeshWorkGroupSizeZ_EXT, maxMeshWorkGroupSizeZ_EXT,
max_mesh_work_group_size_z_ext)
RESOURCE(MaxTaskWorkGroupSizeX_EXT, maxTaskWorkGroupSizeX_EXT,
max_task_work_group_size_x_ext)
RESOURCE(MaxTaskWorkGroupSizeY_EXT, maxTaskWorkGroupSizeY_EXT,
max_task_work_group_size_y_ext)
RESOURCE(MaxTaskWorkGroupSizeZ_EXT, maxTaskWorkGroupSizeZ_EXT,
max_task_work_group_size_z_ext)
RESOURCE(MaxMeshViewCountEXT, maxMeshViewCountEXT, max_mesh_view_count_ext)
RESOURCE(MaxDualSourceDrawBuffersEXT, maxDualSourceDrawBuffersEXT,
max_dual_source_draw_buffers_ext)

View File

@@ -0,0 +1,36 @@
// 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 LIBSHADERC_UTIL_SHADER_STAGE_H_
#define LIBSHADERC_UTIL_SHADER_STAGE_H_
#include <ostream>
#include <string>
#include <utility>
#include <vector>
#include "glslang/Public/ShaderLang.h"
#include "libshaderc_util/string_piece.h"
namespace shaderc_util {
// Given a string representing a stage, returns the glslang EShLanguage for it.
// If the stage string is not recognized, returns EShLangCount.
EShLanguage MapStageNameToLanguage(
const shaderc_util::string_piece& stage_name);
} // namespace shaderc_util
#endif // LIBSHADERC_UTIL_SHADER_STAGE_H_

View File

@@ -0,0 +1,68 @@
// 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 LIBSHADERC_UTIL_INC_SPIRV_TOOLS_WRAPPER_H
#define LIBSHADERC_UTIL_INC_SPIRV_TOOLS_WRAPPER_H
#include <string>
#include <vector>
#include "spirv-tools/libspirv.hpp"
#include "libshaderc_util/compiler.h"
#include "libshaderc_util/string_piece.h"
namespace shaderc_util {
// Assembles the given assembly. On success, returns true, writes the assembled
// binary to *binary, and clears *errors. Otherwise, writes the error message
// into *errors.
bool SpirvToolsAssemble(Compiler::TargetEnv env,
Compiler::TargetEnvVersion version,
const string_piece assembly, spv_binary* binary,
std::string* errors);
// Disassembles the given binary. Returns true and writes the disassembled text
// to *text_or_error if successful. Otherwise, writes the error message to
// *text_or_error.
bool SpirvToolsDisassemble(Compiler::TargetEnv env,
Compiler::TargetEnvVersion version,
const std::vector<uint32_t>& binary,
std::string* text_or_error);
// The ids of a list of supported optimization passes.
enum class PassId {
// SPIRV-Tools standard recipes
kLegalizationPasses,
kPerformancePasses,
kSizePasses,
// SPIRV-Tools specific passes
kNullPass,
kStripDebugInfo,
kCompactIds,
};
// Optimizes the given binary. Passes are registered in the exact order as shown
// in enabled_passes, without de-duplication. Returns true and writes the
// optimized binary back to *binary if successful. Otherwise, writes errors to
// *errors and the content of binary may be in an invalid state.
bool SpirvToolsOptimize(Compiler::TargetEnv env,
Compiler::TargetEnvVersion version,
const std::vector<PassId>& enabled_passes,
spvtools::OptimizerOptions& optimizer_options,
std::vector<uint32_t>* binary, std::string* errors);
} // namespace shaderc_util
#endif // LIBSHADERC_UTIL_INC_SPIRV_TOOLS_WRAPPER_H

View File

@@ -0,0 +1,357 @@
// 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 LIBSHADERC_UTIL_STRING_PIECE_H_
#define LIBSHADERC_UTIL_STRING_PIECE_H_
#include <cassert>
#include <cstring>
#include <ostream>
#include <vector>
namespace shaderc_util {
// Provides a read-only view into a string (cstring or std::string).
// This must be created after the string in question, and cannot
// outlive the memory of the string in question.
// Any operations that may modify the location or size of the
// original data render the associated string_piece invalid.
class string_piece {
public:
typedef const char* iterator;
static const size_t npos = -1;
string_piece() {}
string_piece(const char* begin, const char* end) : begin_(begin), end_(end) {
assert((begin == nullptr) == (end == nullptr) &&
"either both begin and end must be nullptr or neither must be");
}
string_piece(const char* string) : begin_(string), end_(string) {
if (string) {
end_ += strlen(string);
}
}
string_piece(const std::string& str) {
if (!str.empty()) {
begin_ = &(str.front());
end_ = &(str.back()) + 1;
}
}
string_piece(const string_piece& other) {
begin_ = other.begin_;
end_ = other.end_;
}
string_piece& operator=(const string_piece& other) = default;
// Clears the string_piece removing any reference to the original string.
void clear() {
begin_ = nullptr;
end_ = nullptr;
}
// Returns a pointer to the data contained in the underlying string.
// If there is no underlying string, returns a nullptr.
const char* data() const { return begin_; }
// Returns an std::string copy of the internal data.
std::string str() const { return std::string(begin_, end_); }
// Returns a string_piece that points to a substring in the original string.
string_piece substr(size_t pos, size_t len = npos) const {
assert(len == npos || pos + len <= size());
return string_piece(begin_ + pos, len == npos ? end_ : begin_ + pos + len);
}
// Takes any function object predicate that takes a char and returns a
// boolean.
// Returns the index of the first element that does not return true for the
// predicate.
// Returns string_piece::npos if all elements match.
template <typename T>
size_t find_first_not_matching(T callee) {
for (auto it = begin_; it != end_; ++it) {
if (!callee(*it)) {
return it - begin_;
}
}
return npos;
}
// Returns the index of the first character that does not match any character
// in the input string_piece.
// The search only includes characters at or after position pos.
// Returns string_piece::npos if all match.
size_t find_first_not_of(const string_piece& to_search,
size_t pos = 0) const {
if (pos >= size()) {
return npos;
}
for (auto it = begin_ + pos; it != end_; ++it) {
if (to_search.find_first_of(*it) == npos) {
return it - begin_;
}
}
return npos;
}
// Returns find_first_not_of(str, pos) where str is a string_piece
// containing only to_search.
size_t find_first_not_of(char to_search, size_t pos = 0) const {
return find_first_not_of(string_piece(&to_search, &to_search + 1), pos);
}
// Returns the index of the first character that matches any character in the
// input string_piece.
// The search only includes characters at or after position pos.
// Returns string_piece::npos if there is no match.
size_t find_first_of(const string_piece& to_search, size_t pos = 0) const {
if (pos >= size()) {
return npos;
}
for (auto it = begin_ + pos; it != end_; ++it) {
for (char c : to_search) {
if (c == *it) {
return it - begin_;
}
}
}
return npos;
}
// Returns find_first_of(str, pos) where str is a string_piece
// containing only to_search.
size_t find_first_of(char to_search, size_t pos = 0) const {
return find_first_of(string_piece(&to_search, &to_search + 1), pos);
}
// Returns the index of the last character that matches any character in the
// input string_piece.
// The search only includes characters at or before position pos.
// Returns string_piece::npos if there is no match.
size_t find_last_of(const string_piece& to_search, size_t pos = npos) const {
if (empty()) return npos;
if (pos >= size()) {
pos = size();
}
auto it = begin_ + pos + 1;
do {
--it;
if (to_search.find_first_of(*it) != npos) {
return it - begin_;
}
} while (it != begin_);
return npos;
}
// Returns find_last_of(str, pos) where str is a string_piece
// containing only to_search.
size_t find_last_of(char to_search, size_t pos = npos) const {
return find_last_of(string_piece(&to_search, &to_search + 1), pos);
}
// Returns the index of the last character that does not match any character
// in the input string_piece.
// The search only includes characters at or before position pos.
// Returns string_piece::npos if there is no match.
size_t find_last_not_of(const string_piece& to_search,
size_t pos = npos) const {
if (empty()) return npos;
if (pos >= size()) {
pos = size();
}
auto it = begin_ + pos + 1;
do {
--it;
if (to_search.find_first_of(*it) == npos) {
return it - begin_;
}
} while (it != begin_);
return npos;
}
// Returns find_last_not_of(str, pos) where str is a string_piece
// containing only to_search.
size_t find_last_not_of(char to_search, size_t pos = 0) const {
return find_last_not_of(string_piece(&to_search, &to_search + 1), pos);
}
// Continuously removes characters appearing in chars_to_strip from the left.
string_piece lstrip(const string_piece& chars_to_strip) const {
iterator begin = begin_;
for (; begin < end_; ++begin)
if (chars_to_strip.find_first_of(*begin) == npos) break;
if (begin >= end_) return string_piece();
return string_piece(begin, end_);
}
// Continuously removes characters appearing in chars_to_strip from the right.
string_piece rstrip(const string_piece& chars_to_strip) const {
iterator end = end_;
for (; begin_ < end; --end)
if (chars_to_strip.find_first_of(*(end - 1)) == npos) break;
if (begin_ >= end) return string_piece();
return string_piece(begin_, end);
}
// Continuously removes characters appearing in chars_to_strip from both
// sides.
string_piece strip(const string_piece& chars_to_strip) const {
return lstrip(chars_to_strip).rstrip(chars_to_strip);
}
string_piece strip_whitespace() const { return strip(" \t\n\r\f\v"); }
// Returns the character at index i in the string_piece.
const char& operator[](size_t i) const { return *(begin_ + i); }
// Standard comparison operator.
bool operator==(const string_piece& other) const {
// Either end_ and _begin_ are nullptr or neither of them are.
assert(((end_ == nullptr) == (begin_ == nullptr)));
assert(((other.end_ == nullptr) == (other.begin_ == nullptr)));
if (size() != other.size()) {
return false;
}
return (memcmp(begin_, other.begin_, end_ - begin_) == 0);
}
bool operator!=(const string_piece& other) const {
return !operator==(other);
}
// Returns an iterator to the first element.
iterator begin() const { return begin_; }
// Returns an iterator to one past the last element.
iterator end() const { return end_; }
const char& front() const {
assert(!empty());
return *begin_;
}
const char& back() const {
assert(!empty());
return *(end_ - 1);
}
// Returns true is this string_piece starts with the same
// characters as other.
bool starts_with(const string_piece& other) const {
const char* iter = begin_;
const char* other_iter = other.begin();
while (iter != end_ && other_iter != other.end()) {
if (*iter++ != *other_iter++) {
return false;
}
}
return other_iter == other.end();
}
// Returns the index of the start of the first substring that matches
// the input string_piece.
// The search only includes substrings starting at or after position pos.
// Returns npos if the string cannot be found.
size_t find(const string_piece& substr, size_t pos = 0) const {
if (empty()) return npos;
if (pos >= size()) return npos;
if (substr.empty()) return 0;
for (auto it = begin_ + pos;
end() - it >= static_cast<decltype(end() - it)>(substr.size()); ++it) {
if (string_piece(it, end()).starts_with(substr)) return it - begin_;
}
return npos;
}
// Returns the index of the start of the first character that matches
// the input character.
// The search only includes substrings starting at or after position pos.
// Returns npos if the character cannot be found.
size_t find(char character, size_t pos = 0) const {
return find_first_of(character, pos);
}
// Returns true if the string_piece is empty.
bool empty() const { return begin_ == end_; }
// Returns the number of characters in the string_piece.
size_t size() const { return end_ - begin_; }
// Returns a vector of string_pieces representing delimiter delimited
// fields found. If the keep_delimiter parameter is true, then each
// delimiter character is kept with the string to its left.
std::vector<string_piece> get_fields(char delimiter,
bool keep_delimiter = false) const {
std::vector<string_piece> fields;
size_t first = 0;
size_t field_break = find_first_of(delimiter);
while (field_break != npos) {
fields.push_back(substr(first, field_break - first + keep_delimiter));
first = field_break + 1;
field_break = find_first_of(delimiter, first);
}
if (size() - first > 0) {
fields.push_back(substr(first, size() - first));
}
return fields;
}
friend std::ostream& operator<<(std::ostream& os, const string_piece& piece);
private:
// It is expected that begin_ and end_ will both be null or
// they will both point to valid pieces of memory, but it is invalid
// to have one of them being nullptr and the other not.
string_piece::iterator begin_ = nullptr;
string_piece::iterator end_ = nullptr;
};
inline std::ostream& operator<<(std::ostream& os, const string_piece& piece) {
// Either end_ and _begin_ are nullptr or neither of them are.
assert(((piece.end_ == nullptr) == (piece.begin_ == nullptr)));
if (piece.end_ != piece.begin_) {
os.write(piece.begin_, piece.end_ - piece.begin_);
}
return os;
}
inline bool operator==(const char* first, const string_piece second) {
return second == string_piece(first);
}
inline bool operator!=(const char* first, const string_piece second) {
return !operator==(first, second);
}
}
namespace std {
template <>
struct hash<shaderc_util::string_piece> {
size_t operator()(const shaderc_util::string_piece& piece) const {
// djb2 algorithm.
size_t hash = 5381;
for (char c : piece) {
hash = ((hash << 5) + hash) + c;
}
return hash;
}
};
}
#endif // LIBSHADERC_UTIL_STRING_PIECE_H_

View File

@@ -0,0 +1,32 @@
// 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 LIBSHADERC_UTIL_UNIVERSAL_UNISTD_H_
#define LIBSHADERC_UTIL_UNIVERSAL_UNISTD_H_
#ifndef _MSC_VER
#include <unistd.h>
#else
// Minimal set of <unistd> needed to compile on windows.
#include <io.h>
#define access _access
// https://msdn.microsoft.com/en-us/library/1w06ktdy.aspx
// Defines these constants.
#define R_OK 4
#define W_OK 2
#endif //_MSC_VER
#endif // LIBSHADERC_UTIL_UNIVERSAL_UNISTD_H_

View File

@@ -0,0 +1,61 @@
// 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 LIBSHADERC_UTIL_INC_VERSION_PROFILE_H_
#define LIBSHADERC_UTIL_INC_VERSION_PROFILE_H_
#include <string>
#include "glslang/MachineIndependent/Versions.h"
namespace shaderc_util {
// Returns true if the given version is an accepted GLSL (ES) version.
inline bool IsKnownVersion(int version) {
switch (version) {
case 100:
case 110:
case 120:
case 130:
case 140:
case 150:
case 300:
case 310:
case 320:
case 330:
case 400:
case 410:
case 420:
case 430:
case 440:
case 450:
case 460:
return true;
default:
break;
}
return false;
}
// Given a string version_profile containing both version and profile, decodes
// it and puts the decoded version in version, decoded profile in profile.
// Returns true if decoding is successful and version and profile are accepted.
// This does not validate the version number against the profile. For example,
// "460es" doesn't make sense (yet), but is still accepted.
bool ParseVersionProfile(const std::string& version_profile, int* version,
EProfile* profile);
} // namespace shaderc_util
#endif // LIBSHADERC_UTIL_INC_VERSION_PROFILE_H_