Android Build Tools
This commit is contained in:
32
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/Android.mk
vendored
Normal file
32
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/Android.mk
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
# Copyright 2020 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.
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE:=shaderc_util
|
||||
LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti -DENABLE_HLSL=1
|
||||
LOCAL_EXPORT_C_INCLUDES:=$(LOCAL_PATH)/include
|
||||
LOCAL_SRC_FILES:=src/args.cc \
|
||||
src/compiler.cc \
|
||||
src/file_finder.cc \
|
||||
src/io_shaderc.cc \
|
||||
src/message.cc \
|
||||
src/resources.cc \
|
||||
src/shader_stage.cc \
|
||||
src/spirv_tools_wrapper.cc \
|
||||
src/version_profile.cc
|
||||
LOCAL_STATIC_LIBRARIES:=SPIRV SPIRV-Tools-opt
|
||||
LOCAL_C_INCLUDES:=$(LOCAL_PATH)/include
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
@ -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
|
||||
@ -0,0 +1,628 @@
|
||||
// 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),
|
||||
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),
|
||||
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();
|
||||
|
||||
// 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 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 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_;
|
||||
|
||||
// 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 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 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
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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_
|
||||
@ -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_
|
||||
@ -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_
|
||||
@ -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_
|
||||
107
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/include/libshaderc_util/mutex.h
vendored
Normal file
107
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/include/libshaderc_util/mutex.h
vendored
Normal 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
|
||||
@ -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_
|
||||
@ -0,0 +1,107 @@
|
||||
// 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)
|
||||
@ -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_
|
||||
@ -0,0 +1,67 @@
|
||||
// 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,
|
||||
std::vector<uint32_t>* binary, std::string* errors);
|
||||
|
||||
} // namespace shaderc_util
|
||||
|
||||
#endif // LIBSHADERC_UTIL_INC_SPIRV_TOOLS_WRAPPER_H
|
||||
@ -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 == 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_
|
||||
@ -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_
|
||||
@ -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_
|
||||
62
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/src/args.cc
vendored
Normal file
62
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/src/args.cc
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
// 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.
|
||||
|
||||
#include "libshaderc_util/args.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
namespace shaderc_util {
|
||||
|
||||
bool GetOptionArgument(int argc, char** argv, int* index,
|
||||
const std::string& option,
|
||||
string_piece* option_argument) {
|
||||
const string_piece arg = argv[*index];
|
||||
assert(arg.starts_with(option));
|
||||
if (arg.size() != option.size()) {
|
||||
*option_argument = arg.substr(option.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (option.back() == '=') {
|
||||
*option_argument = "";
|
||||
return true;
|
||||
}
|
||||
|
||||
if (++(*index) >= argc) return false;
|
||||
*option_argument = argv[*index];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParseUint32(const std::string& str, uint32_t* value) {
|
||||
std::istringstream iss(str);
|
||||
|
||||
iss >> std::setbase(0);
|
||||
iss >> *value;
|
||||
|
||||
// We should have read something.
|
||||
bool ok = !str.empty() && !iss.bad();
|
||||
// It should have been all the text.
|
||||
ok = ok && iss.eof();
|
||||
// It should have been in range.
|
||||
ok = ok && !iss.fail();
|
||||
|
||||
// Work around a bugs in various C++ standard libraries.
|
||||
// Count any negative number as an error, including "-0".
|
||||
ok = ok && (str[0] != '-');
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
} // namespace shaderc_util
|
||||
793
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/src/compiler.cc
vendored
Normal file
793
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/src/compiler.cc
vendored
Normal file
@ -0,0 +1,793 @@
|
||||
// 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 "libshaderc_util/compiler.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
#include <tuple>
|
||||
|
||||
#include "SPIRV/GlslangToSpv.h"
|
||||
#include "libshaderc_util/format.h"
|
||||
#include "libshaderc_util/io_shaderc.h"
|
||||
#include "libshaderc_util/message.h"
|
||||
#include "libshaderc_util/resources.h"
|
||||
#include "libshaderc_util/shader_stage.h"
|
||||
#include "libshaderc_util/spirv_tools_wrapper.h"
|
||||
#include "libshaderc_util/string_piece.h"
|
||||
#include "libshaderc_util/version_profile.h"
|
||||
|
||||
namespace {
|
||||
using shaderc_util::string_piece;
|
||||
|
||||
// For use with glslang parsing calls.
|
||||
const bool kNotForwardCompatible = false;
|
||||
|
||||
// Returns true if #line directive sets the line number for the next line in the
|
||||
// given version and profile.
|
||||
inline bool LineDirectiveIsForNextLine(int version, EProfile profile) {
|
||||
return profile == EEsProfile || version >= 330;
|
||||
}
|
||||
|
||||
// Returns a #line directive whose arguments are line and filename.
|
||||
inline std::string GetLineDirective(int line, const string_piece& filename) {
|
||||
return "#line " + std::to_string(line) + " \"" + filename.str() + "\"\n";
|
||||
}
|
||||
|
||||
// Given a canonicalized #line directive (starting exactly with "#line", using
|
||||
// single spaces to separate different components, and having an optional
|
||||
// newline at the end), returns the line number and string name/number. If no
|
||||
// string name/number is provided, the second element in the returned pair is an
|
||||
// empty string_piece. Behavior is undefined if the directive parameter is not a
|
||||
// canonicalized #line directive.
|
||||
std::pair<int, string_piece> DecodeLineDirective(string_piece directive) {
|
||||
const string_piece kLineDirective = "#line ";
|
||||
assert(directive.starts_with(kLineDirective));
|
||||
directive = directive.substr(kLineDirective.size());
|
||||
|
||||
const int line = std::atoi(directive.data());
|
||||
const size_t space_loc = directive.find_first_of(' ');
|
||||
if (space_loc == string_piece::npos) return std::make_pair(line, "");
|
||||
|
||||
directive = directive.substr(space_loc);
|
||||
directive = directive.strip("\" \n");
|
||||
return std::make_pair(line, directive);
|
||||
}
|
||||
|
||||
// Returns the Glslang message rules for the given target environment,
|
||||
// source language, and whether we want HLSL offset rules. We assume
|
||||
// only valid combinations are used.
|
||||
EShMessages GetMessageRules(shaderc_util::Compiler::TargetEnv env,
|
||||
shaderc_util::Compiler::SourceLanguage lang,
|
||||
bool hlsl_offsets, bool hlsl_16bit_types,
|
||||
bool debug_info) {
|
||||
using shaderc_util::Compiler;
|
||||
EShMessages result = EShMsgCascadingErrors;
|
||||
if (lang == Compiler::SourceLanguage::HLSL) {
|
||||
result = static_cast<EShMessages>(result | EShMsgReadHlsl);
|
||||
}
|
||||
switch (env) {
|
||||
case Compiler::TargetEnv::OpenGLCompat:
|
||||
// The compiler will have already errored out before now.
|
||||
// But we need to handle this enum.
|
||||
break;
|
||||
case Compiler::TargetEnv::OpenGL:
|
||||
result = static_cast<EShMessages>(result | EShMsgSpvRules);
|
||||
break;
|
||||
case Compiler::TargetEnv::Vulkan:
|
||||
result =
|
||||
static_cast<EShMessages>(result | EShMsgSpvRules | EShMsgVulkanRules);
|
||||
break;
|
||||
}
|
||||
if (hlsl_offsets) {
|
||||
result = static_cast<EShMessages>(result | EShMsgHlslOffsets);
|
||||
}
|
||||
if (hlsl_16bit_types) {
|
||||
result = static_cast<EShMessages>(result | EShMsgHlslEnable16BitTypes);
|
||||
}
|
||||
if (debug_info) {
|
||||
result = static_cast<EShMessages>(result | EShMsgDebugInfo);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace shaderc_util {
|
||||
|
||||
unsigned int GlslangInitializer::initialize_count_ = 0;
|
||||
std::mutex* GlslangInitializer::glslang_mutex_ = nullptr;
|
||||
|
||||
GlslangInitializer::GlslangInitializer() {
|
||||
static std::mutex first_call_mutex;
|
||||
|
||||
// If this is the first call, glslang_mutex_ needs to be created, but in
|
||||
// thread safe manner.
|
||||
{
|
||||
const std::lock_guard<std::mutex> first_call_lock(first_call_mutex);
|
||||
if (glslang_mutex_ == nullptr) {
|
||||
glslang_mutex_ = new std::mutex();
|
||||
}
|
||||
}
|
||||
|
||||
const std::lock_guard<std::mutex> glslang_lock(*glslang_mutex_);
|
||||
|
||||
if (initialize_count_ == 0) {
|
||||
glslang::InitializeProcess();
|
||||
}
|
||||
|
||||
initialize_count_++;
|
||||
}
|
||||
|
||||
GlslangInitializer::~GlslangInitializer() {
|
||||
const std::lock_guard<std::mutex> glslang_lock(*glslang_mutex_);
|
||||
|
||||
initialize_count_--;
|
||||
|
||||
if (initialize_count_ == 0) {
|
||||
glslang::FinalizeProcess();
|
||||
// There is no delete for glslang_mutex_ here, because we cannot guarantee
|
||||
// there isn't a caller waiting for glslang_mutex_ in GlslangInitializer().
|
||||
//
|
||||
// This means that this class does leak one std::mutex worth of memory after
|
||||
// the final instance is destroyed, but this allows us to defer allocating
|
||||
// and constructing until we are sure we need to.
|
||||
}
|
||||
}
|
||||
|
||||
void Compiler::SetLimit(Compiler::Limit limit, int value) {
|
||||
switch (limit) {
|
||||
#define RESOURCE(NAME, FIELD, CNAME) \
|
||||
case Limit::NAME: \
|
||||
limits_.FIELD = value; \
|
||||
break;
|
||||
#include "libshaderc_util/resources.inc"
|
||||
#undef RESOURCE
|
||||
}
|
||||
}
|
||||
|
||||
int Compiler::GetLimit(Compiler::Limit limit) const {
|
||||
switch (limit) {
|
||||
#define RESOURCE(NAME, FIELD, CNAME) \
|
||||
case Limit::NAME: \
|
||||
return limits_.FIELD;
|
||||
#include "libshaderc_util/resources.inc"
|
||||
#undef RESOURCE
|
||||
}
|
||||
return 0; // Unreachable
|
||||
}
|
||||
|
||||
std::tuple<bool, std::vector<uint32_t>, size_t> Compiler::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 {
|
||||
// Compilation results to be returned:
|
||||
// Initialize the result tuple as a failed compilation. In error cases, we
|
||||
// should return result_tuple directly without setting its members.
|
||||
auto result_tuple =
|
||||
std::make_tuple(false, std::vector<uint32_t>(), (size_t)0u);
|
||||
// Get the reference of the members of the result tuple. We should set their
|
||||
// values for succeeded compilation before returning the result tuple.
|
||||
bool& succeeded = std::get<0>(result_tuple);
|
||||
std::vector<uint32_t>& compilation_output_data = std::get<1>(result_tuple);
|
||||
size_t& compilation_output_data_size_in_bytes = std::get<2>(result_tuple);
|
||||
|
||||
// Check target environment.
|
||||
const auto target_client_info = GetGlslangClientInfo(
|
||||
error_tag, target_env_, target_env_version_,
|
||||
target_spirv_version_, target_spirv_version_is_forced_);
|
||||
if (!target_client_info.error.empty()) {
|
||||
*error_stream << target_client_info.error;
|
||||
*total_warnings = 0;
|
||||
*total_errors = 1;
|
||||
return result_tuple;
|
||||
}
|
||||
|
||||
EShLanguage used_shader_stage = forced_shader_stage;
|
||||
const std::string macro_definitions =
|
||||
shaderc_util::format(predefined_macros_, "#define ", " ", "\n");
|
||||
const std::string pound_extension =
|
||||
"#extension GL_GOOGLE_include_directive : enable\n";
|
||||
const std::string preamble = macro_definitions + pound_extension;
|
||||
|
||||
std::string preprocessed_shader;
|
||||
|
||||
// If only preprocessing, we definitely need to preprocess. Otherwise, if
|
||||
// we don't know the stage until now, we need the preprocessed shader to
|
||||
// deduce the shader stage.
|
||||
if (output_type == OutputType::PreprocessedText ||
|
||||
used_shader_stage == EShLangCount) {
|
||||
bool success;
|
||||
std::string glslang_errors;
|
||||
std::tie(success, preprocessed_shader, glslang_errors) =
|
||||
PreprocessShader(error_tag, input_source_string, preamble, includer);
|
||||
|
||||
success &= PrintFilteredErrors(error_tag, error_stream, warnings_as_errors_,
|
||||
/* suppress_warnings = */ true,
|
||||
glslang_errors.c_str(), total_warnings,
|
||||
total_errors);
|
||||
if (!success) return result_tuple;
|
||||
// Because of the behavior change of the #line directive, the #line
|
||||
// directive introducing each file's content must use the syntax for the
|
||||
// specified version. So we need to probe this shader's version and
|
||||
// profile.
|
||||
int version;
|
||||
EProfile profile;
|
||||
std::tie(version, profile) = DeduceVersionProfile(preprocessed_shader);
|
||||
const bool is_for_next_line = LineDirectiveIsForNextLine(version, profile);
|
||||
|
||||
preprocessed_shader =
|
||||
CleanupPreamble(preprocessed_shader, error_tag, pound_extension,
|
||||
includer.num_include_directives(), is_for_next_line);
|
||||
|
||||
if (output_type == OutputType::PreprocessedText) {
|
||||
// Set the values of the result tuple.
|
||||
succeeded = true;
|
||||
compilation_output_data = ConvertStringToVector(preprocessed_shader);
|
||||
compilation_output_data_size_in_bytes = preprocessed_shader.size();
|
||||
return result_tuple;
|
||||
} else if (used_shader_stage == EShLangCount) {
|
||||
std::string errors;
|
||||
std::tie(used_shader_stage, errors) =
|
||||
GetShaderStageFromSourceCode(error_tag, preprocessed_shader);
|
||||
if (!errors.empty()) {
|
||||
*error_stream << errors;
|
||||
return result_tuple;
|
||||
}
|
||||
if (used_shader_stage == EShLangCount) {
|
||||
if ((used_shader_stage = stage_callback(error_stream, error_tag)) ==
|
||||
EShLangCount) {
|
||||
return result_tuple;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parsing requires its own Glslang symbol tables.
|
||||
glslang::TShader shader(used_shader_stage);
|
||||
const char* shader_strings = input_source_string.data();
|
||||
const int shader_lengths = static_cast<int>(input_source_string.size());
|
||||
const char* string_names = error_tag.c_str();
|
||||
shader.setStringsWithLengthsAndNames(&shader_strings, &shader_lengths,
|
||||
&string_names, 1);
|
||||
shader.setPreamble(preamble.c_str());
|
||||
shader.setEntryPoint(entry_point_name);
|
||||
shader.setAutoMapBindings(auto_bind_uniforms_);
|
||||
if (auto_combined_image_sampler_) {
|
||||
shader.setTextureSamplerTransformMode(EShTexSampTransUpgradeTextureRemoveSampler);
|
||||
}
|
||||
shader.setAutoMapLocations(auto_map_locations_);
|
||||
const auto& bases = auto_binding_base_[static_cast<int>(used_shader_stage)];
|
||||
shader.setShiftImageBinding(bases[static_cast<int>(UniformKind::Image)]);
|
||||
shader.setShiftSamplerBinding(bases[static_cast<int>(UniformKind::Sampler)]);
|
||||
shader.setShiftTextureBinding(bases[static_cast<int>(UniformKind::Texture)]);
|
||||
shader.setShiftUboBinding(bases[static_cast<int>(UniformKind::Buffer)]);
|
||||
shader.setShiftSsboBinding(
|
||||
bases[static_cast<int>(UniformKind::StorageBuffer)]);
|
||||
shader.setShiftUavBinding(
|
||||
bases[static_cast<int>(UniformKind::UnorderedAccessView)]);
|
||||
shader.setHlslIoMapping(hlsl_iomap_);
|
||||
shader.setResourceSetBinding(
|
||||
hlsl_explicit_bindings_[static_cast<int>(used_shader_stage)]);
|
||||
shader.setEnvClient(target_client_info.client,
|
||||
target_client_info.client_version);
|
||||
shader.setEnvTarget(target_client_info.target_language,
|
||||
target_client_info.target_language_version);
|
||||
if (hlsl_functionality1_enabled_) {
|
||||
shader.setEnvTargetHlslFunctionality1();
|
||||
}
|
||||
shader.setInvertY(invert_y_enabled_);
|
||||
shader.setNanMinMaxClamp(nan_clamp_);
|
||||
|
||||
const EShMessages rules =
|
||||
GetMessageRules(target_env_, source_language_, hlsl_offsets_,
|
||||
hlsl_16bit_types_enabled_, generate_debug_info_);
|
||||
|
||||
bool success = shader.parse(&limits_, default_version_, default_profile_,
|
||||
force_version_profile_, kNotForwardCompatible,
|
||||
rules, includer);
|
||||
|
||||
success &= PrintFilteredErrors(error_tag, error_stream, warnings_as_errors_,
|
||||
suppress_warnings_, shader.getInfoLog(),
|
||||
total_warnings, total_errors);
|
||||
if (!success) return result_tuple;
|
||||
|
||||
glslang::TProgram program;
|
||||
program.addShader(&shader);
|
||||
success = program.link(EShMsgDefault) && program.mapIO();
|
||||
success &= PrintFilteredErrors(error_tag, error_stream, warnings_as_errors_,
|
||||
suppress_warnings_, program.getInfoLog(),
|
||||
total_warnings, total_errors);
|
||||
if (!success) return result_tuple;
|
||||
|
||||
// 'spirv' is an alias for the compilation_output_data. This alias is added
|
||||
// to serve as an input for the call to DissassemblyBinary.
|
||||
std::vector<uint32_t>& spirv = compilation_output_data;
|
||||
glslang::SpvOptions options;
|
||||
options.generateDebugInfo = generate_debug_info_;
|
||||
options.disableOptimizer = true;
|
||||
options.optimizeSize = false;
|
||||
// Note the call to GlslangToSpv also populates compilation_output_data.
|
||||
glslang::GlslangToSpv(*program.getIntermediate(used_shader_stage), spirv,
|
||||
&options);
|
||||
|
||||
// Set the tool field (the top 16-bits) in the generator word to
|
||||
// 'Shaderc over Glslang'.
|
||||
const uint32_t shaderc_generator_word = 13; // From SPIR-V XML Registry
|
||||
const uint32_t generator_word_index = 2; // SPIR-V 2.3: Physical layout
|
||||
assert(spirv.size() > generator_word_index);
|
||||
spirv[generator_word_index] =
|
||||
(spirv[generator_word_index] & 0xffff) | (shaderc_generator_word << 16);
|
||||
|
||||
std::vector<PassId> opt_passes;
|
||||
|
||||
if (hlsl_legalization_enabled_ && source_language_ == SourceLanguage::HLSL) {
|
||||
// If from HLSL, run this passes to "legalize" the SPIR-V for Vulkan
|
||||
// eg. forward and remove memory writes of opaque types.
|
||||
opt_passes.push_back(PassId::kLegalizationPasses);
|
||||
}
|
||||
|
||||
opt_passes.insert(opt_passes.end(), enabled_opt_passes_.begin(),
|
||||
enabled_opt_passes_.end());
|
||||
|
||||
if (!opt_passes.empty()) {
|
||||
std::string opt_errors;
|
||||
if (!SpirvToolsOptimize(target_env_, target_env_version_,
|
||||
opt_passes, &spirv, &opt_errors)) {
|
||||
*error_stream << "shaderc: internal error: compilation succeeded but "
|
||||
"failed to optimize: "
|
||||
<< opt_errors << "\n";
|
||||
return result_tuple;
|
||||
}
|
||||
}
|
||||
|
||||
if (output_type == OutputType::SpirvAssemblyText) {
|
||||
std::string text_or_error;
|
||||
if (!SpirvToolsDisassemble(target_env_, target_env_version_, spirv,
|
||||
&text_or_error)) {
|
||||
*error_stream << "shaderc: internal error: compilation succeeded but "
|
||||
"failed to disassemble: "
|
||||
<< text_or_error << "\n";
|
||||
return result_tuple;
|
||||
}
|
||||
succeeded = true;
|
||||
compilation_output_data = ConvertStringToVector(text_or_error);
|
||||
compilation_output_data_size_in_bytes = text_or_error.size();
|
||||
return result_tuple;
|
||||
} else {
|
||||
succeeded = true;
|
||||
// Note compilation_output_data is already populated in GlslangToSpv().
|
||||
compilation_output_data_size_in_bytes = spirv.size() * sizeof(spirv[0]);
|
||||
return result_tuple;
|
||||
}
|
||||
}
|
||||
|
||||
void Compiler::AddMacroDefinition(const char* macro, size_t macro_length,
|
||||
const char* definition,
|
||||
size_t definition_length) {
|
||||
predefined_macros_[std::string(macro, macro_length)] =
|
||||
definition ? std::string(definition, definition_length) : "";
|
||||
}
|
||||
|
||||
void Compiler::SetTargetEnv(Compiler::TargetEnv env,
|
||||
Compiler::TargetEnvVersion version) {
|
||||
target_env_ = env;
|
||||
target_env_version_ = version;
|
||||
}
|
||||
|
||||
void Compiler::SetTargetSpirv(Compiler::SpirvVersion version) {
|
||||
target_spirv_version_ = version;
|
||||
target_spirv_version_is_forced_ = true;
|
||||
}
|
||||
|
||||
void Compiler::SetSourceLanguage(Compiler::SourceLanguage lang) {
|
||||
source_language_ = lang;
|
||||
}
|
||||
|
||||
void Compiler::SetForcedVersionProfile(int version, EProfile profile) {
|
||||
default_version_ = version;
|
||||
default_profile_ = profile;
|
||||
force_version_profile_ = true;
|
||||
}
|
||||
|
||||
void Compiler::SetWarningsAsErrors() { warnings_as_errors_ = true; }
|
||||
|
||||
void Compiler::SetGenerateDebugInfo() {
|
||||
generate_debug_info_ = true;
|
||||
for (size_t i = 0; i < enabled_opt_passes_.size(); ++i) {
|
||||
if (enabled_opt_passes_[i] == PassId::kStripDebugInfo) {
|
||||
enabled_opt_passes_[i] = PassId::kNullPass;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Compiler::SetOptimizationLevel(Compiler::OptimizationLevel level) {
|
||||
// Clear previous settings first.
|
||||
enabled_opt_passes_.clear();
|
||||
|
||||
switch (level) {
|
||||
case OptimizationLevel::Size:
|
||||
if (!generate_debug_info_) {
|
||||
enabled_opt_passes_.push_back(PassId::kStripDebugInfo);
|
||||
}
|
||||
enabled_opt_passes_.push_back(PassId::kSizePasses);
|
||||
break;
|
||||
case OptimizationLevel::Performance:
|
||||
if (!generate_debug_info_) {
|
||||
enabled_opt_passes_.push_back(PassId::kStripDebugInfo);
|
||||
}
|
||||
enabled_opt_passes_.push_back(PassId::kPerformancePasses);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Compiler::EnableHlslLegalization(bool hlsl_legalization_enabled) {
|
||||
hlsl_legalization_enabled_ = hlsl_legalization_enabled;
|
||||
}
|
||||
|
||||
void Compiler::EnableHlslFunctionality1(bool enable) {
|
||||
hlsl_functionality1_enabled_ = enable;
|
||||
}
|
||||
|
||||
void Compiler::EnableHlsl16BitTypes(bool enable) {
|
||||
hlsl_16bit_types_enabled_ = enable;
|
||||
}
|
||||
|
||||
void Compiler::EnableInvertY(bool enable) { invert_y_enabled_ = enable; }
|
||||
|
||||
void Compiler::SetNanClamp(bool enable) { nan_clamp_ = enable; }
|
||||
|
||||
void Compiler::SetSuppressWarnings() { suppress_warnings_ = true; }
|
||||
|
||||
std::tuple<bool, std::string, std::string> Compiler::PreprocessShader(
|
||||
const std::string& error_tag, const string_piece& shader_source,
|
||||
const string_piece& shader_preamble, CountingIncluder& includer) const {
|
||||
// The stage does not matter for preprocessing.
|
||||
glslang::TShader shader(EShLangVertex);
|
||||
const char* shader_strings = shader_source.data();
|
||||
const int shader_lengths = static_cast<int>(shader_source.size());
|
||||
const char* string_names = error_tag.c_str();
|
||||
shader.setStringsWithLengthsAndNames(&shader_strings, &shader_lengths,
|
||||
&string_names, 1);
|
||||
shader.setPreamble(shader_preamble.data());
|
||||
auto target_client_info = GetGlslangClientInfo(
|
||||
error_tag, target_env_, target_env_version_,
|
||||
target_spirv_version_, target_spirv_version_is_forced_);
|
||||
if (!target_client_info.error.empty()) {
|
||||
return std::make_tuple(false, "", target_client_info.error);
|
||||
}
|
||||
shader.setEnvClient(target_client_info.client,
|
||||
target_client_info.client_version);
|
||||
if (hlsl_functionality1_enabled_) {
|
||||
shader.setEnvTargetHlslFunctionality1();
|
||||
}
|
||||
shader.setInvertY(invert_y_enabled_);
|
||||
shader.setNanMinMaxClamp(nan_clamp_);
|
||||
|
||||
// The preprocessor might be sensitive to the target environment.
|
||||
// So combine the existing rules with the just-give-me-preprocessor-output
|
||||
// flag.
|
||||
const auto rules = static_cast<EShMessages>(
|
||||
EShMsgOnlyPreprocessor |
|
||||
GetMessageRules(target_env_, source_language_, hlsl_offsets_,
|
||||
hlsl_16bit_types_enabled_, false));
|
||||
|
||||
std::string preprocessed_shader;
|
||||
const bool success = shader.preprocess(
|
||||
&limits_, default_version_, default_profile_, force_version_profile_,
|
||||
kNotForwardCompatible, rules, &preprocessed_shader, includer);
|
||||
|
||||
if (success) {
|
||||
return std::make_tuple(true, preprocessed_shader, shader.getInfoLog());
|
||||
}
|
||||
return std::make_tuple(false, "", shader.getInfoLog());
|
||||
}
|
||||
|
||||
std::string Compiler::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 {
|
||||
// Those #define directives in preamble will become empty lines after
|
||||
// preprocessing. We also injected an #extension directive to turn on #include
|
||||
// directive support. In the original preprocessing output from glslang, it
|
||||
// appears before the user source string. We need to do proper adjustment:
|
||||
// * Remove empty lines generated from #define directives in preamble.
|
||||
// * If there is no #include directive in the source code, we do not need to
|
||||
// output the injected #extension directive. Otherwise,
|
||||
// * If there exists a #version directive in the source code, it should be
|
||||
// placed at the first line. Its original line will be filled with an empty
|
||||
// line as placeholder to maintain the code structure.
|
||||
|
||||
const std::vector<string_piece> lines =
|
||||
preprocessed_shader.get_fields('\n', /* keep_delimiter = */ true);
|
||||
|
||||
std::ostringstream output_stream;
|
||||
|
||||
size_t pound_extension_index = lines.size();
|
||||
size_t pound_version_index = lines.size();
|
||||
for (size_t i = 0; i < lines.size(); ++i) {
|
||||
if (lines[i] == pound_extension) {
|
||||
pound_extension_index = std::min(i, pound_extension_index);
|
||||
} else if (lines[i].starts_with("#version")) {
|
||||
// In a preprocessed shader, directives are in a canonical format, so we
|
||||
// can confidently compare to '#version' verbatim, without worrying about
|
||||
// whitespace.
|
||||
pound_version_index = i;
|
||||
if (num_include_directives > 0) output_stream << lines[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// We know that #extension directive exists and appears before #version
|
||||
// directive (if any).
|
||||
assert(pound_extension_index < lines.size());
|
||||
|
||||
for (size_t i = 0; i < pound_extension_index; ++i) {
|
||||
// All empty lines before the #line directive we injected are generated by
|
||||
// preprocessing preamble. Do not output them.
|
||||
if (lines[i].strip_whitespace().empty()) continue;
|
||||
output_stream << lines[i];
|
||||
}
|
||||
|
||||
if (num_include_directives > 0) {
|
||||
output_stream << pound_extension;
|
||||
// Also output a #line directive for the main file.
|
||||
output_stream << GetLineDirective(is_for_next_line, error_tag);
|
||||
}
|
||||
|
||||
for (size_t i = pound_extension_index + 1; i < lines.size(); ++i) {
|
||||
if (i == pound_version_index) {
|
||||
if (num_include_directives > 0) {
|
||||
output_stream << "\n";
|
||||
} else {
|
||||
output_stream << lines[i];
|
||||
}
|
||||
} else {
|
||||
output_stream << lines[i];
|
||||
}
|
||||
}
|
||||
|
||||
return output_stream.str();
|
||||
}
|
||||
|
||||
std::pair<EShLanguage, std::string> Compiler::GetShaderStageFromSourceCode(
|
||||
string_piece filename, const std::string& preprocessed_shader) const {
|
||||
const string_piece kPragmaShaderStageDirective = "#pragma shader_stage";
|
||||
const string_piece kLineDirective = "#line";
|
||||
|
||||
int version;
|
||||
EProfile profile;
|
||||
std::tie(version, profile) = DeduceVersionProfile(preprocessed_shader);
|
||||
const bool is_for_next_line = LineDirectiveIsForNextLine(version, profile);
|
||||
|
||||
std::vector<string_piece> lines =
|
||||
string_piece(preprocessed_shader).get_fields('\n');
|
||||
// The filename, logical line number (which starts from 1 and is sensitive to
|
||||
// #line directives), and stage value for #pragma shader_stage() directives.
|
||||
std::vector<std::tuple<string_piece, size_t, string_piece>> stages;
|
||||
// The physical line numbers of the first #pragma shader_stage() line and
|
||||
// first non-preprocessing line in the preprocessed shader text.
|
||||
size_t first_pragma_physical_line = lines.size() + 1;
|
||||
size_t first_non_pp_line = lines.size() + 1;
|
||||
|
||||
for (size_t i = 0, logical_line_no = 1; i < lines.size(); ++i) {
|
||||
const string_piece current_line = lines[i].strip_whitespace();
|
||||
if (current_line.starts_with(kPragmaShaderStageDirective)) {
|
||||
const string_piece stage_value =
|
||||
current_line.substr(kPragmaShaderStageDirective.size()).strip("()");
|
||||
stages.emplace_back(filename, logical_line_no, stage_value);
|
||||
first_pragma_physical_line = std::min(first_pragma_physical_line, i + 1);
|
||||
} else if (!current_line.empty() && !current_line.starts_with("#")) {
|
||||
first_non_pp_line = std::min(first_non_pp_line, i + 1);
|
||||
}
|
||||
|
||||
// Update logical line number for the next line.
|
||||
if (current_line.starts_with(kLineDirective)) {
|
||||
string_piece name;
|
||||
std::tie(logical_line_no, name) = DecodeLineDirective(current_line);
|
||||
if (!name.empty()) filename = name;
|
||||
// Note that for core profile, the meaning of #line changed since version
|
||||
// 330. The line number given by #line used to mean the logical line
|
||||
// number of the #line line. Now it means the logical line number of the
|
||||
// next line after the #line line.
|
||||
if (!is_for_next_line) ++logical_line_no;
|
||||
} else {
|
||||
++logical_line_no;
|
||||
}
|
||||
}
|
||||
if (stages.empty()) return std::make_pair(EShLangCount, "");
|
||||
|
||||
std::string error_message;
|
||||
|
||||
const string_piece& first_pragma_filename = std::get<0>(stages[0]);
|
||||
const std::string first_pragma_line = std::to_string(std::get<1>(stages[0]));
|
||||
const string_piece& first_pragma_stage = std::get<2>(stages[0]);
|
||||
|
||||
if (first_pragma_physical_line > first_non_pp_line) {
|
||||
error_message += first_pragma_filename.str() + ":" + first_pragma_line +
|
||||
": error: '#pragma': the first 'shader_stage' #pragma "
|
||||
"must appear before any non-preprocessing code\n";
|
||||
}
|
||||
|
||||
EShLanguage stage = MapStageNameToLanguage(first_pragma_stage);
|
||||
if (stage == EShLangCount) {
|
||||
error_message +=
|
||||
first_pragma_filename.str() + ":" + first_pragma_line +
|
||||
": error: '#pragma': invalid stage for 'shader_stage' #pragma: '" +
|
||||
first_pragma_stage.str() + "'\n";
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < stages.size(); ++i) {
|
||||
const string_piece& current_stage = std::get<2>(stages[i]);
|
||||
if (current_stage != first_pragma_stage) {
|
||||
const string_piece& current_filename = std::get<0>(stages[i]);
|
||||
const std::string current_line = std::to_string(std::get<1>(stages[i]));
|
||||
error_message += current_filename.str() + ":" + current_line +
|
||||
": error: '#pragma': conflicting stages for "
|
||||
"'shader_stage' #pragma: '" +
|
||||
current_stage.str() + "' (was '" +
|
||||
first_pragma_stage.str() + "' at " +
|
||||
first_pragma_filename.str() + ":" + first_pragma_line +
|
||||
")\n";
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_pair(error_message.empty() ? stage : EShLangCount,
|
||||
error_message);
|
||||
}
|
||||
|
||||
std::pair<int, EProfile> Compiler::DeduceVersionProfile(
|
||||
const std::string& preprocessed_shader) const {
|
||||
int version = default_version_;
|
||||
EProfile profile = default_profile_;
|
||||
if (!force_version_profile_) {
|
||||
std::tie(version, profile) =
|
||||
GetVersionProfileFromSourceCode(preprocessed_shader);
|
||||
if (version == 0 && profile == ENoProfile) {
|
||||
version = default_version_;
|
||||
profile = default_profile_;
|
||||
}
|
||||
}
|
||||
return std::make_pair(version, profile);
|
||||
}
|
||||
|
||||
std::pair<int, EProfile> Compiler::GetVersionProfileFromSourceCode(
|
||||
const std::string& preprocessed_shader) const {
|
||||
string_piece pound_version = preprocessed_shader;
|
||||
const size_t pound_version_loc = pound_version.find("#version");
|
||||
if (pound_version_loc == string_piece::npos) {
|
||||
return std::make_pair(0, ENoProfile);
|
||||
}
|
||||
pound_version =
|
||||
pound_version.substr(pound_version_loc + std::strlen("#version"));
|
||||
pound_version = pound_version.substr(0, pound_version.find_first_of("\n"));
|
||||
|
||||
std::string version_profile;
|
||||
for (const auto character : pound_version) {
|
||||
if (character != ' ') version_profile += character;
|
||||
}
|
||||
|
||||
int version;
|
||||
EProfile profile;
|
||||
if (!ParseVersionProfile(version_profile, &version, &profile)) {
|
||||
return std::make_pair(0, ENoProfile);
|
||||
}
|
||||
return std::make_pair(version, profile);
|
||||
}
|
||||
|
||||
// Converts a string to a vector of uint32_t by copying the content of a given
|
||||
// string to a vector<uint32_t> 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) {
|
||||
size_t num_bytes_str = str.size() + 1u;
|
||||
size_t vector_length =
|
||||
(num_bytes_str + sizeof(uint32_t) - 1) / sizeof(uint32_t);
|
||||
std::vector<uint32_t> result_vec(vector_length, 0);
|
||||
std::strncpy(reinterpret_cast<char*>(result_vec.data()), str.c_str(),
|
||||
str.size());
|
||||
return result_vec;
|
||||
}
|
||||
|
||||
GlslangClientInfo GetGlslangClientInfo(
|
||||
const std::string& error_tag, shaderc_util::Compiler::TargetEnv env,
|
||||
shaderc_util::Compiler::TargetEnvVersion env_version,
|
||||
shaderc_util::Compiler::SpirvVersion spv_version,
|
||||
bool spv_version_is_forced) {
|
||||
GlslangClientInfo result;
|
||||
std::ostringstream errs;
|
||||
|
||||
using shaderc_util::Compiler;
|
||||
switch (env) {
|
||||
case Compiler::TargetEnv::Vulkan:
|
||||
result.client = glslang::EShClientVulkan;
|
||||
if (env_version == Compiler::TargetEnvVersion::Default ||
|
||||
env_version == Compiler::TargetEnvVersion::Vulkan_1_0) {
|
||||
result.client_version = glslang::EShTargetVulkan_1_0;
|
||||
} else if (env_version == Compiler::TargetEnvVersion::Vulkan_1_1) {
|
||||
result.client_version = glslang::EShTargetVulkan_1_1;
|
||||
result.target_language_version = glslang::EShTargetSpv_1_3;
|
||||
} else if (env_version == Compiler::TargetEnvVersion::Vulkan_1_2) {
|
||||
result.client_version = glslang::EShTargetVulkan_1_2;
|
||||
result.target_language_version = glslang::EShTargetSpv_1_5;
|
||||
} else if (env_version == Compiler::TargetEnvVersion::Vulkan_1_3) {
|
||||
result.client_version = glslang::EShTargetVulkan_1_3;
|
||||
result.target_language_version = glslang::EShTargetSpv_1_6;
|
||||
} else {
|
||||
errs << "error:" << error_tag << ": Invalid target client version "
|
||||
<< static_cast<uint32_t>(env_version) << " for Vulkan environment "
|
||||
<< int(env);
|
||||
}
|
||||
break;
|
||||
case Compiler::TargetEnv::OpenGLCompat:
|
||||
errs << "error: OpenGL compatibility profile is not supported";
|
||||
break;
|
||||
case Compiler::TargetEnv::OpenGL:
|
||||
result.client = glslang::EShClientOpenGL;
|
||||
if (env_version == Compiler::TargetEnvVersion::Default ||
|
||||
env_version == Compiler::TargetEnvVersion::OpenGL_4_5) {
|
||||
result.client_version = glslang::EShTargetOpenGL_450;
|
||||
} else {
|
||||
errs << "error:" << error_tag << ": Invalid target client version "
|
||||
<< static_cast<uint32_t>(env_version) << " for OpenGL environment "
|
||||
<< int(env);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
errs << "error:" << error_tag << ": Invalid target client environment "
|
||||
<< int(env);
|
||||
break;
|
||||
}
|
||||
|
||||
if (spv_version_is_forced && errs.str().empty()) {
|
||||
switch (spv_version) {
|
||||
case Compiler::SpirvVersion::v1_0:
|
||||
result.target_language_version = glslang::EShTargetSpv_1_0;
|
||||
break;
|
||||
case Compiler::SpirvVersion::v1_1:
|
||||
result.target_language_version = glslang::EShTargetSpv_1_1;
|
||||
break;
|
||||
case Compiler::SpirvVersion::v1_2:
|
||||
result.target_language_version = glslang::EShTargetSpv_1_2;
|
||||
break;
|
||||
case Compiler::SpirvVersion::v1_3:
|
||||
result.target_language_version = glslang::EShTargetSpv_1_3;
|
||||
break;
|
||||
case Compiler::SpirvVersion::v1_4:
|
||||
result.target_language_version = glslang::EShTargetSpv_1_4;
|
||||
break;
|
||||
case Compiler::SpirvVersion::v1_5:
|
||||
result.target_language_version = glslang::EShTargetSpv_1_5;
|
||||
break;
|
||||
case Compiler::SpirvVersion::v1_6:
|
||||
result.target_language_version = glslang::EShTargetSpv_1_6;
|
||||
break;
|
||||
default:
|
||||
errs << "error:" << error_tag << ": Unknown SPIR-V version " << std::hex
|
||||
<< uint32_t(spv_version);
|
||||
break;
|
||||
}
|
||||
}
|
||||
result.error = errs.str();
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace shaderc_util
|
||||
71
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/src/file_finder.cc
vendored
Normal file
71
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/src/file_finder.cc
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
// 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 "libshaderc_util/file_finder.h"
|
||||
#include "libshaderc_util/string_piece.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <fstream>
|
||||
#include <ios>
|
||||
|
||||
namespace {
|
||||
|
||||
// Returns "" if path is empty or ends in '/'. Otherwise, returns "/".
|
||||
std::string MaybeSlash(const shaderc_util::string_piece& path) {
|
||||
return (path.empty() || path.back() == '/') ? "" : "/";
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace shaderc_util {
|
||||
|
||||
std::string FileFinder::FindReadableFilepath(
|
||||
const std::string& filename) const {
|
||||
assert(!filename.empty());
|
||||
static const auto for_reading = std::ios_base::in;
|
||||
std::filebuf opener;
|
||||
for (const auto& prefix : search_path_) {
|
||||
const std::string prefixed_filename =
|
||||
prefix + MaybeSlash(prefix) + filename;
|
||||
if (opener.open(prefixed_filename, for_reading)) return prefixed_filename;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string FileFinder::FindRelativeReadableFilepath(
|
||||
const std::string& requesting_file, const std::string& filename) const {
|
||||
assert(!filename.empty());
|
||||
|
||||
string_piece dir_name(requesting_file);
|
||||
|
||||
size_t last_slash = requesting_file.find_last_of("/\\");
|
||||
if (last_slash != std::string::npos) {
|
||||
dir_name = string_piece(requesting_file.c_str(),
|
||||
requesting_file.c_str() + last_slash);
|
||||
}
|
||||
|
||||
if (dir_name.size() == requesting_file.size()) {
|
||||
dir_name.clear();
|
||||
}
|
||||
|
||||
static const auto for_reading = std::ios_base::in;
|
||||
std::filebuf opener;
|
||||
const std::string relative_filename =
|
||||
dir_name.str() + MaybeSlash(dir_name) + filename;
|
||||
if (opener.open(relative_filename, for_reading)) return relative_filename;
|
||||
|
||||
return FindReadableFilepath(filename);
|
||||
}
|
||||
|
||||
} // namespace shaderc_util
|
||||
146
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/src/io_shaderc.cc
vendored
Normal file
146
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/src/io_shaderc.cc
vendored
Normal file
@ -0,0 +1,146 @@
|
||||
// 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 "libshaderc_util/io_shaderc.h"
|
||||
|
||||
#include "libshaderc_util/universal_unistd.h"
|
||||
|
||||
#if _WIN32
|
||||
// Need _fileno from stdio.h
|
||||
// Need _O_BINARY and _O_TEXT from fcntl.h
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
|
||||
// Outputs a descriptive message for errno_value to cerr.
|
||||
// This may be truncated to 1023 bytes on certain platforms.
|
||||
void OutputFileErrorMessage(int errno_value) {
|
||||
#ifdef _MSC_VER
|
||||
// If the error message is more than 1023 bytes it will be truncated.
|
||||
char buffer[1024];
|
||||
strerror_s(buffer, errno_value);
|
||||
std::cerr << ": " << buffer << std::endl;
|
||||
#else
|
||||
std::cerr << ": " << strerror(errno_value) << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace shaderc_util {
|
||||
|
||||
bool IsAbsolutePath(const std::string& path) {
|
||||
if (path.empty()) return false;
|
||||
// Unix-like OS: /path/to/file
|
||||
if (path.front() == '/') return true;
|
||||
// Windows: \\server\user\file
|
||||
if (path.size() > 1 && path[0] == '\\' && path[1] == '\\') {
|
||||
return true;
|
||||
}
|
||||
// Windows: X:\path\to\file
|
||||
if (path.size() > 2 && ::isalpha(path[0]) && path[1] == ':' &&
|
||||
path[2] == '\\') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string GetBaseFileName(const std::string& file_path) {
|
||||
size_t loc_slash = file_path.find_last_of("/\\");
|
||||
std::string base_name =
|
||||
file_path.substr((loc_slash == std::string::npos ? -1 : loc_slash) + 1);
|
||||
if (base_name == ".." || base_name == ".") {
|
||||
base_name = "";
|
||||
}
|
||||
return base_name;
|
||||
}
|
||||
|
||||
bool ReadFile(const std::string& input_file_name,
|
||||
std::vector<char>* input_data) {
|
||||
std::istream* stream = &std::cin;
|
||||
std::ifstream input_file;
|
||||
if (input_file_name != "-") {
|
||||
input_file.open(input_file_name, std::ios_base::binary);
|
||||
stream = &input_file;
|
||||
if (input_file.fail()) {
|
||||
std::cerr << "glslc: error: cannot open input file: '" << input_file_name
|
||||
<< "'";
|
||||
if (access(input_file_name.c_str(), R_OK) != 0) {
|
||||
OutputFileErrorMessage(errno);
|
||||
return false;
|
||||
}
|
||||
std::cerr << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
*input_data = std::vector<char>((std::istreambuf_iterator<char>(*stream)),
|
||||
std::istreambuf_iterator<char>());
|
||||
return true;
|
||||
}
|
||||
|
||||
std::ostream* GetOutputStream(const string_piece& output_filename,
|
||||
std::ofstream* file_stream, std::ostream* err) {
|
||||
std::ostream* stream = &std::cout;
|
||||
if (output_filename != "-") {
|
||||
file_stream->open(output_filename.str(), std::ios_base::binary);
|
||||
stream = file_stream;
|
||||
if (file_stream->fail()) {
|
||||
*err << "glslc: error: cannot open output file: '" << output_filename
|
||||
<< "'";
|
||||
if (access(output_filename.str().c_str(), W_OK) != 0) {
|
||||
OutputFileErrorMessage(errno);
|
||||
return nullptr;
|
||||
}
|
||||
std::cerr << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
bool WriteFile(std::ostream* stream, const string_piece& output_data) {
|
||||
if (output_data.size() > 0) {
|
||||
stream->write(output_data.data(), output_data.size());
|
||||
if (!stream->good()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
stream->flush();
|
||||
return true;
|
||||
}
|
||||
|
||||
void FlushAndSetBinaryModeOnStdout() {
|
||||
std::fflush(stdout);
|
||||
#if _WIN32
|
||||
_setmode(_fileno(stdout), _O_BINARY);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FlushAndSetTextModeOnStdout() {
|
||||
std::fflush(stdout);
|
||||
#if _WIN32
|
||||
_setmode(_fileno(stdout), _O_TEXT);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace shaderc_util
|
||||
293
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/src/message.cc
vendored
Normal file
293
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/src/message.cc
vendored
Normal file
@ -0,0 +1,293 @@
|
||||
// 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 "libshaderc_util/message.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
|
||||
namespace shaderc_util {
|
||||
|
||||
namespace {
|
||||
|
||||
// Given a message, deduces and returns its type. If the message type is
|
||||
// recognized, advances *message past the prefix indicating the type. Otherwise,
|
||||
// leaves *message unchanged and returns MessageType::Unknown.
|
||||
MessageType DeduceMessageType(string_piece* message) {
|
||||
static const char kErrorMessage[] = "ERROR: ";
|
||||
static const char kWarningMessage[] = "WARNING: ";
|
||||
static const char kGlobalWarningMessage[] = "Warning, ";
|
||||
|
||||
if (message->starts_with(kErrorMessage)) {
|
||||
*message = message->substr(::strlen(kErrorMessage));
|
||||
return MessageType::Error;
|
||||
} else if (message->starts_with(kWarningMessage)) {
|
||||
*message = message->substr(::strlen(kWarningMessage));
|
||||
return MessageType::Warning;
|
||||
} else if (message->starts_with(kGlobalWarningMessage)) {
|
||||
*message = message->substr(::strlen(kGlobalWarningMessage));
|
||||
return MessageType::GlobalWarning;
|
||||
}
|
||||
return MessageType::Unknown;
|
||||
}
|
||||
|
||||
// Deduces a location specification from the given message. A location
|
||||
// specification is of the form "<source-name>:<line-number>:" and a trailing
|
||||
// space. If the deduction is successful, returns true and updates source_name
|
||||
// and line_number to the deduced source name and line numer respectively. The
|
||||
// prefix standing for the location specification in message is skipped.
|
||||
// Otherwise, returns false and keeps all parameters untouched.
|
||||
bool DeduceLocationSpec(string_piece* message, string_piece* source_name,
|
||||
string_piece* line_number) {
|
||||
if (!message || message->empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// When we find a pattern like this:
|
||||
// colon
|
||||
// digits
|
||||
// colon
|
||||
// space
|
||||
// Then deduce that the source_name is the text before the first colon,
|
||||
// the line number is the digits, and the message is the text after the
|
||||
// second colon.
|
||||
|
||||
const size_t size = message->size();
|
||||
if (size <= 4) {
|
||||
// A valid message must have a colon, a digit, a colon, and a space.
|
||||
return false;
|
||||
}
|
||||
// The last possible position of the first colon.
|
||||
const size_t first_colon_cutoff = size - 4;
|
||||
// The last possible position of the second colon.
|
||||
const size_t next_colon_cutoff = size - 2;
|
||||
|
||||
for (size_t first_colon_pos = message->find_first_of(':'), next_colon_pos = 0;
|
||||
|
||||
// There is a first colon, and it's not too close to the end
|
||||
(first_colon_pos != string_piece::npos) &&
|
||||
(first_colon_pos <= first_colon_cutoff);
|
||||
|
||||
// Try the next pair of colons.
|
||||
first_colon_pos = next_colon_pos) {
|
||||
// We're guaranteed to have at least 3 more characters.
|
||||
// Guarantee progress toward the end of the string.
|
||||
next_colon_pos = message->find_first_of(':', first_colon_pos + 1);
|
||||
if ((next_colon_pos == string_piece::npos) ||
|
||||
(next_colon_pos > next_colon_cutoff)) {
|
||||
// No valid solution.
|
||||
return false;
|
||||
}
|
||||
if (first_colon_pos + 1 == next_colon_pos) {
|
||||
// There is no room for digits.
|
||||
continue;
|
||||
}
|
||||
if ((message->data()[next_colon_pos + 1] != ' ')) {
|
||||
// There is no space character after the second colon.
|
||||
continue;
|
||||
}
|
||||
if (message->find_first_not_of("0123456789", first_colon_pos + 1) ==
|
||||
next_colon_pos) {
|
||||
// We found the first solution.
|
||||
*source_name = message->substr(0, first_colon_pos);
|
||||
*line_number = message->substr(first_colon_pos + 1,
|
||||
next_colon_pos - 1 - first_colon_pos);
|
||||
*message = message->substr(next_colon_pos + 2);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns true if the given message is a summary message.
|
||||
bool IsSummaryMessage(const string_piece& message) {
|
||||
const size_t space_loc = message.find_first_of(' ');
|
||||
if (space_loc == string_piece::npos) return false;
|
||||
const string_piece number = message.substr(0, space_loc);
|
||||
const string_piece rest = message.substr(space_loc + 1);
|
||||
if (!std::all_of(number.begin(), number.end(), ::isdigit)) return false;
|
||||
if (!rest.starts_with("compilation errors.")) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
MessageType ParseGlslangOutput(const string_piece& message,
|
||||
bool warnings_as_errors, bool suppress_warnings,
|
||||
string_piece* source_name,
|
||||
string_piece* line_number, string_piece* rest) {
|
||||
string_piece rest_of_message(message);
|
||||
source_name->clear();
|
||||
line_number->clear();
|
||||
rest->clear();
|
||||
|
||||
// The glslang warning/error messages are typically of the following form:
|
||||
// <message-type> <location-specification> <message-body>
|
||||
//
|
||||
// <message-type> can be "WARNING:", "ERROR:", or "Warning, ". "WARNING:"
|
||||
// means a warning message for a certain line, while "Warning, " means a
|
||||
// global one.
|
||||
//
|
||||
// <location-specification> is of the form:
|
||||
// <filename-or-string-number>:<line-number>:
|
||||
// It doesn't exist if the warning/error message is a global one.
|
||||
//
|
||||
// See Glslang's TInfoSink class implementation for details.
|
||||
|
||||
bool is_error = false;
|
||||
|
||||
// Handle <message-type>.
|
||||
switch (DeduceMessageType(&rest_of_message)) {
|
||||
case MessageType::Warning:
|
||||
if (suppress_warnings) return MessageType::Ignored;
|
||||
break;
|
||||
case MessageType::Error:
|
||||
is_error = true;
|
||||
break;
|
||||
case MessageType::GlobalWarning:
|
||||
if (suppress_warnings) return MessageType::Ignored;
|
||||
*rest = rest_of_message;
|
||||
return warnings_as_errors ? MessageType::GlobalError
|
||||
: MessageType::GlobalWarning;
|
||||
case MessageType::Unknown:
|
||||
*rest = rest_of_message;
|
||||
return MessageType::Unknown;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
rest_of_message = rest_of_message.strip_whitespace();
|
||||
if (rest_of_message.empty()) return MessageType::Unknown;
|
||||
|
||||
// Now we have stripped the <message-type>. Try to see if we can find
|
||||
// a <location-specification>.
|
||||
if (DeduceLocationSpec(&rest_of_message, source_name, line_number)) {
|
||||
*rest = rest_of_message;
|
||||
return (is_error || warnings_as_errors) ? MessageType::Error
|
||||
: MessageType::Warning;
|
||||
} else {
|
||||
// No <location-specification>. This is a global warning/error message.
|
||||
// A special kind of global message is summary message, which should
|
||||
// start with a number.
|
||||
*rest = rest_of_message;
|
||||
if (IsSummaryMessage(rest_of_message)) {
|
||||
return (is_error || warnings_as_errors) ? MessageType::ErrorSummary
|
||||
: MessageType::WarningSummary;
|
||||
}
|
||||
return (is_error || warnings_as_errors) ? MessageType::GlobalError
|
||||
: MessageType::GlobalWarning;
|
||||
}
|
||||
return MessageType::Unknown;
|
||||
}
|
||||
|
||||
bool PrintFilteredErrors(const 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) {
|
||||
const char* ignored_error_strings[] = {
|
||||
"Warning, version 310 is not yet complete; most version-specific "
|
||||
"features are present, but some are missing.",
|
||||
"Warning, version 400 is not yet complete; most version-specific "
|
||||
"features are present, but some are missing.",
|
||||
"Warning, version 410 is not yet complete; most version-specific "
|
||||
"features are present, but some are missing.",
|
||||
"Warning, version 420 is not yet complete; most version-specific "
|
||||
"features are present, but some are missing.",
|
||||
"Warning, version 430 is not yet complete; most version-specific "
|
||||
"features are present, but some are missing.",
|
||||
"Warning, version 440 is not yet complete; most version-specific "
|
||||
"features are present, but some are missing.",
|
||||
"Warning, version 450 is not yet complete; most version-specific "
|
||||
"features are present, but some are missing.",
|
||||
"Linked vertex stage:", "Linked fragment stage:",
|
||||
"Linked tessellation control stage:",
|
||||
"Linked tessellation evaluation stage:", "Linked geometry stage:",
|
||||
"Linked compute stage:", ""};
|
||||
size_t existing_total_errors = *total_errors;
|
||||
string_piece error_messages(error_list);
|
||||
for (const string_piece& message : error_messages.get_fields('\n')) {
|
||||
if (std::find(std::begin(ignored_error_strings),
|
||||
std::end(ignored_error_strings),
|
||||
message) == std::end(ignored_error_strings)) {
|
||||
string_piece source_name;
|
||||
string_piece line_number;
|
||||
string_piece rest;
|
||||
const MessageType type =
|
||||
ParseGlslangOutput(message, warnings_as_errors, suppress_warnings,
|
||||
&source_name, &line_number, &rest);
|
||||
string_piece name = file_name;
|
||||
if (!source_name.empty()) {
|
||||
// -1 is the string number for the preamble injected by us.
|
||||
name = source_name == "-1" ? "<command line>" : source_name;
|
||||
}
|
||||
switch (type) {
|
||||
case MessageType::Error:
|
||||
case MessageType::Warning:
|
||||
assert(!name.empty() && !line_number.empty() && !rest.empty());
|
||||
*error_stream << name << ":" << line_number << ": "
|
||||
<< (type == MessageType::Error ? "error: "
|
||||
: "warning: ")
|
||||
<< rest.strip_whitespace() << std::endl;
|
||||
*total_errors += type == MessageType::Error;
|
||||
*total_warnings += type == MessageType::Warning;
|
||||
break;
|
||||
case MessageType::ErrorSummary:
|
||||
case MessageType::WarningSummary:
|
||||
break;
|
||||
case MessageType::GlobalError:
|
||||
case MessageType::GlobalWarning:
|
||||
assert(!rest.empty());
|
||||
*total_errors += type == MessageType::GlobalError;
|
||||
*total_warnings += type == MessageType::GlobalWarning;
|
||||
*error_stream << name << ": "
|
||||
<< (type == MessageType::GlobalError ? "error"
|
||||
: "warning")
|
||||
<< ": " << rest.strip_whitespace() << std::endl;
|
||||
break;
|
||||
case MessageType::Unknown:
|
||||
*error_stream << name << ":";
|
||||
*error_stream << " " << message << std::endl;
|
||||
break;
|
||||
case MessageType::Ignored:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (existing_total_errors == *total_errors);
|
||||
}
|
||||
|
||||
// Outputs the number of warnings and errors if there are any.
|
||||
void OutputMessages(std::ostream* error_stream, size_t total_warnings,
|
||||
size_t total_errors) {
|
||||
if (total_warnings > 0 || total_errors > 0) {
|
||||
if (total_warnings > 0 && total_errors > 0) {
|
||||
*error_stream << total_warnings << " warning"
|
||||
<< (total_warnings > 1 ? "s" : "") << " and "
|
||||
<< total_errors << " error" << (total_errors > 1 ? "s" : "")
|
||||
<< " generated." << std::endl;
|
||||
} else if (total_warnings > 0) {
|
||||
*error_stream << total_warnings << " warning"
|
||||
<< (total_warnings > 1 ? "s" : "") << " generated."
|
||||
<< std::endl;
|
||||
} else if (total_errors > 0) {
|
||||
*error_stream << total_errors << " error" << (total_errors > 1 ? "s" : "")
|
||||
<< " generated." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace glslc
|
||||
153
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/src/resources.cc
vendored
Normal file
153
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/src/resources.cc
vendored
Normal file
@ -0,0 +1,153 @@
|
||||
// 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 "libshaderc_util/resources.h"
|
||||
|
||||
#include "glslang/Include/ResourceLimits.h"
|
||||
|
||||
namespace shaderc_util {
|
||||
|
||||
// These numbers come from the OpenGL 4.4 core profile specification Chapter 23
|
||||
// unless otherwise specified.
|
||||
const TBuiltInResource kDefaultTBuiltInResource = {
|
||||
/*.maxLights = */ 8, // From OpenGL 3.0 table 6.46.
|
||||
/*.maxClipPlanes = */ 6, // From OpenGL 3.0 table 6.46.
|
||||
/*.maxTextureUnits = */ 2, // From OpenGL 3.0 table 6.50.
|
||||
/*.maxTextureCoords = */ 8, // From OpenGL 3.0 table 6.50.
|
||||
/*.maxVertexAttribs = */ 16,
|
||||
/*.maxVertexUniformComponents = */ 4096,
|
||||
/*.maxVaryingFloats = */ 60, // From OpenGLES 3.1 table 6.44.
|
||||
/*.maxVertexTextureImageUnits = */ 16,
|
||||
/*.maxCombinedTextureImageUnits = */ 80,
|
||||
/*.maxTextureImageUnits = */ 16,
|
||||
/*.maxFragmentUniformComponents = */ 1024,
|
||||
|
||||
// glslang has 32 maxDrawBuffers.
|
||||
// Pixel phone Vulkan driver in Android N has 8
|
||||
// maxFragmentOutputAttachments.
|
||||
/*.maxDrawBuffers = */ 8,
|
||||
|
||||
/*.maxVertexUniformVectors = */ 256,
|
||||
/*.maxVaryingVectors = */ 15, // From OpenGLES 3.1 table 6.44.
|
||||
/*.maxFragmentUniformVectors = */ 256,
|
||||
/*.maxVertexOutputVectors = */ 16, // maxVertexOutputComponents / 4
|
||||
/*.maxFragmentInputVectors = */ 15, // maxFragmentInputComponents / 4
|
||||
/*.minProgramTexelOffset = */ -8,
|
||||
/*.maxProgramTexelOffset = */ 7,
|
||||
/*.maxClipDistances = */ 8,
|
||||
/*.maxComputeWorkGroupCountX = */ 65535,
|
||||
/*.maxComputeWorkGroupCountY = */ 65535,
|
||||
/*.maxComputeWorkGroupCountZ = */ 65535,
|
||||
/*.maxComputeWorkGroupSizeX = */ 1024,
|
||||
/*.maxComputeWorkGroupSizeX = */ 1024,
|
||||
/*.maxComputeWorkGroupSizeZ = */ 64,
|
||||
/*.maxComputeUniformComponents = */ 512,
|
||||
/*.maxComputeTextureImageUnits = */ 16,
|
||||
/*.maxComputeImageUniforms = */ 8,
|
||||
/*.maxComputeAtomicCounters = */ 8,
|
||||
/*.maxComputeAtomicCounterBuffers = */ 1, // From OpenGLES 3.1 Table 6.43
|
||||
/*.maxVaryingComponents = */ 60,
|
||||
/*.maxVertexOutputComponents = */ 64,
|
||||
/*.maxGeometryInputComponents = */ 64,
|
||||
/*.maxGeometryOutputComponents = */ 128,
|
||||
/*.maxFragmentInputComponents = */ 128,
|
||||
/*.maxImageUnits = */ 8, // This does not seem to be defined anywhere,
|
||||
// set to ImageUnits.
|
||||
/*.maxCombinedImageUnitsAndFragmentOutputs = */ 8,
|
||||
/*.maxCombinedShaderOutputResources = */ 8,
|
||||
/*.maxImageSamples = */ 0,
|
||||
/*.maxVertexImageUniforms = */ 0,
|
||||
/*.maxTessControlImageUniforms = */ 0,
|
||||
/*.maxTessEvaluationImageUniforms = */ 0,
|
||||
/*.maxGeometryImageUniforms = */ 0,
|
||||
/*.maxFragmentImageUniforms = */ 8,
|
||||
/*.maxCombinedImageUniforms = */ 8,
|
||||
/*.maxGeometryTextureImageUnits = */ 16,
|
||||
/*.maxGeometryOutputVertices = */ 256,
|
||||
/*.maxGeometryTotalOutputComponents = */ 1024,
|
||||
/*.maxGeometryUniformComponents = */ 512,
|
||||
/*.maxGeometryVaryingComponents = */ 60, // Does not seem to be defined
|
||||
// anywhere, set equal to
|
||||
// maxVaryingComponents.
|
||||
/*.maxTessControlInputComponents = */ 128,
|
||||
/*.maxTessControlOutputComponents = */ 128,
|
||||
/*.maxTessControlTextureImageUnits = */ 16,
|
||||
/*.maxTessControlUniformComponents = */ 1024,
|
||||
/*.maxTessControlTotalOutputComponents = */ 4096,
|
||||
/*.maxTessEvaluationInputComponents = */ 128,
|
||||
/*.maxTessEvaluationOutputComponents = */ 128,
|
||||
/*.maxTessEvaluationTextureImageUnits = */ 16,
|
||||
/*.maxTessEvaluationUniformComponents = */ 1024,
|
||||
/*.maxTessPatchComponents = */ 120,
|
||||
/*.maxPatchVertices = */ 32,
|
||||
/*.maxTessGenLevel = */ 64,
|
||||
/*.maxViewports = */ 16,
|
||||
/*.maxVertexAtomicCounters = */ 0,
|
||||
/*.maxTessControlAtomicCounters = */ 0,
|
||||
/*.maxTessEvaluationAtomicCounters = */ 0,
|
||||
/*.maxGeometryAtomicCounters = */ 0,
|
||||
/*.maxFragmentAtomicCounters = */ 8,
|
||||
/*.maxCombinedAtomicCounters = */ 8,
|
||||
/*.maxAtomicCounterBindings = */ 1,
|
||||
/*.maxVertexAtomicCounterBuffers = */ 0, // From OpenGLES 3.1 Table 6.41.
|
||||
|
||||
// ARB_shader_atomic_counters.
|
||||
/*.maxTessControlAtomicCounterBuffers = */ 0,
|
||||
/*.maxTessEvaluationAtomicCounterBuffers = */ 0,
|
||||
/*.maxGeometryAtomicCounterBuffers = */ 0,
|
||||
// /ARB_shader_atomic_counters.
|
||||
|
||||
/*.maxFragmentAtomicCounterBuffers = */ 0, // From OpenGLES 3.1 Table 6.43.
|
||||
/*.maxCombinedAtomicCounterBuffers = */ 1,
|
||||
/*.maxAtomicCounterBufferSize = */ 32,
|
||||
/*.maxTransformFeedbackBuffers = */ 4,
|
||||
/*.maxTransformFeedbackInterleavedComponents = */ 64,
|
||||
/*.maxCullDistances = */ 8, // ARB_cull_distance.
|
||||
/*.maxCombinedClipAndCullDistances = */ 8, // ARB_cull_distance.
|
||||
/*.maxSamples = */ 4,
|
||||
/* .maxMeshOutputVerticesNV = */ 256,
|
||||
/* .maxMeshOutputPrimitivesNV = */ 512,
|
||||
/* .maxMeshWorkGroupSizeX_NV = */ 32,
|
||||
/* .maxMeshWorkGroupSizeY_NV = */ 1,
|
||||
/* .maxMeshWorkGroupSizeZ_NV = */ 1,
|
||||
/* .maxTaskWorkGroupSizeX_NV = */ 32,
|
||||
/* .maxTaskWorkGroupSizeY_NV = */ 1,
|
||||
/* .maxTaskWorkGroupSizeZ_NV = */ 1,
|
||||
/* .maxMeshViewCountNV = */ 4,
|
||||
/* .maxMeshOutputVerticesEXT = */ 256,
|
||||
/* .maxMeshOutputPrimitivesEXT = */ 256,
|
||||
/* .maxMeshWorkGroupSizeX_EXT = */ 128,
|
||||
/* .maxMeshWorkGroupSizeY_EXT = */ 128,
|
||||
/* .maxMeshWorkGroupSizeZ_EXT = */ 128,
|
||||
/* .maxTaskWorkGroupSizeX_EXT = */ 128,
|
||||
/* .maxTaskWorkGroupSizeY_EXT = */ 128,
|
||||
/* .maxTaskWorkGroupSizeZ_EXT = */ 128,
|
||||
/* .maxMeshViewCountEXT = */ 4,
|
||||
/* .maxDualSourceDrawBuffersEXT = */ 1,
|
||||
// This is the glslang TLimits structure.
|
||||
// It defines whether or not the following features are enabled.
|
||||
// We want them to all be enabled.
|
||||
/*.limits = */ {
|
||||
/*.nonInductiveForLoops = */ 1,
|
||||
/*.whileLoops = */ 1,
|
||||
/*.doWhileLoops = */ 1,
|
||||
/*.generalUniformIndexing = */ 1,
|
||||
/*.generalAttributeMatrixVectorIndexing = */ 1,
|
||||
/*.generalVaryingIndexing = */ 1,
|
||||
/*.generalSamplerIndexing = */ 1,
|
||||
/*.generalVariableIndexing = */ 1,
|
||||
/*.generalConstantMatrixVectorIndexing = */ 1,
|
||||
}};
|
||||
|
||||
} // namespace shaderc_util
|
||||
53
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/src/shader_stage.cc
vendored
Normal file
53
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/src/shader_stage.cc
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
// 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 "libshaderc_util/shader_stage.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// Maps an identifier to a language.
|
||||
struct LanguageMapping {
|
||||
const char* id;
|
||||
EShLanguage language;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace shaderc_util {
|
||||
|
||||
EShLanguage MapStageNameToLanguage(const string_piece& stage_name) {
|
||||
const LanguageMapping string_to_stage[] = {
|
||||
{"vertex", EShLangVertex},
|
||||
{"fragment", EShLangFragment},
|
||||
{"tesscontrol", EShLangTessControl},
|
||||
{"tesseval", EShLangTessEvaluation},
|
||||
{"geometry", EShLangGeometry},
|
||||
{"compute", EShLangCompute},
|
||||
{"raygen", EShLangRayGenNV},
|
||||
{"intersect", EShLangIntersectNV},
|
||||
{"anyhit", EShLangAnyHitNV},
|
||||
{"closest", EShLangClosestHitNV},
|
||||
{"miss", EShLangMissNV},
|
||||
{"callable", EShLangCallableNV},
|
||||
{"task", EShLangTaskNV},
|
||||
{"mesh", EShLangMeshNV},
|
||||
};
|
||||
|
||||
for (const auto& entry : string_to_stage) {
|
||||
if (stage_name == entry.id) return entry.language;
|
||||
}
|
||||
return EShLangCount;
|
||||
}
|
||||
|
||||
} // namespace shaderc_util
|
||||
169
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/src/spirv_tools_wrapper.cc
vendored
Normal file
169
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/src/spirv_tools_wrapper.cc
vendored
Normal file
@ -0,0 +1,169 @@
|
||||
// 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 "libshaderc_util/spirv_tools_wrapper.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
#include "spirv-tools/optimizer.hpp"
|
||||
|
||||
namespace shaderc_util {
|
||||
|
||||
namespace {
|
||||
|
||||
// Gets the corresponding target environment used in SPIRV-Tools.
|
||||
spv_target_env GetSpirvToolsTargetEnv(Compiler::TargetEnv env,
|
||||
Compiler::TargetEnvVersion version) {
|
||||
switch (env) {
|
||||
case Compiler::TargetEnv::Vulkan:
|
||||
switch (version) {
|
||||
case Compiler::TargetEnvVersion::Default:
|
||||
return SPV_ENV_VULKAN_1_0;
|
||||
case Compiler::TargetEnvVersion::Vulkan_1_0:
|
||||
return SPV_ENV_VULKAN_1_0;
|
||||
case Compiler::TargetEnvVersion::Vulkan_1_1:
|
||||
return SPV_ENV_VULKAN_1_1;
|
||||
case Compiler::TargetEnvVersion::Vulkan_1_2:
|
||||
return SPV_ENV_VULKAN_1_2;
|
||||
case Compiler::TargetEnvVersion::Vulkan_1_3:
|
||||
return SPV_ENV_VULKAN_1_3;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Compiler::TargetEnv::OpenGL:
|
||||
return SPV_ENV_OPENGL_4_5;
|
||||
case Compiler::TargetEnv::OpenGLCompat:
|
||||
// Errors out before getting here. But the compiler wants us to handle
|
||||
// enum anyway.
|
||||
return SPV_ENV_OPENGL_4_5;
|
||||
}
|
||||
assert(false && "unexpected target environment or version");
|
||||
return SPV_ENV_VULKAN_1_0;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
bool SpirvToolsDisassemble(Compiler::TargetEnv env,
|
||||
Compiler::TargetEnvVersion version,
|
||||
const std::vector<uint32_t>& binary,
|
||||
std::string* text_or_error) {
|
||||
spvtools::SpirvTools tools(GetSpirvToolsTargetEnv(env, version));
|
||||
std::ostringstream oss;
|
||||
tools.SetMessageConsumer([&oss](spv_message_level_t, const char*,
|
||||
const spv_position_t& position,
|
||||
const char* message) {
|
||||
oss << position.index << ": " << message;
|
||||
});
|
||||
const bool success =
|
||||
tools.Disassemble(binary, text_or_error,
|
||||
SPV_BINARY_TO_TEXT_OPTION_INDENT |
|
||||
SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
|
||||
if (!success) {
|
||||
*text_or_error = oss.str();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool SpirvToolsAssemble(Compiler::TargetEnv env,
|
||||
Compiler::TargetEnvVersion version,
|
||||
const string_piece assembly, spv_binary* binary,
|
||||
std::string* errors) {
|
||||
auto spvtools_context =
|
||||
spvContextCreate(GetSpirvToolsTargetEnv(env, version));
|
||||
spv_diagnostic spvtools_diagnostic = nullptr;
|
||||
|
||||
*binary = nullptr;
|
||||
errors->clear();
|
||||
|
||||
const bool success =
|
||||
spvTextToBinary(spvtools_context, assembly.data(), assembly.size(),
|
||||
binary, &spvtools_diagnostic) == SPV_SUCCESS;
|
||||
if (!success) {
|
||||
std::ostringstream oss;
|
||||
oss << spvtools_diagnostic->position.line + 1 << ":"
|
||||
<< spvtools_diagnostic->position.column + 1 << ": "
|
||||
<< spvtools_diagnostic->error;
|
||||
*errors = oss.str();
|
||||
}
|
||||
|
||||
spvDiagnosticDestroy(spvtools_diagnostic);
|
||||
spvContextDestroy(spvtools_context);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool SpirvToolsOptimize(Compiler::TargetEnv env,
|
||||
Compiler::TargetEnvVersion version,
|
||||
const std::vector<PassId>& enabled_passes,
|
||||
std::vector<uint32_t>* binary, std::string* errors) {
|
||||
errors->clear();
|
||||
if (enabled_passes.empty()) return true;
|
||||
if (std::all_of(
|
||||
enabled_passes.cbegin(), enabled_passes.cend(),
|
||||
[](const PassId& pass) { return pass == PassId::kNullPass; })) {
|
||||
return true;
|
||||
}
|
||||
|
||||
spvtools::ValidatorOptions val_opts;
|
||||
// This allows flexible memory layout for HLSL.
|
||||
val_opts.SetSkipBlockLayout(true);
|
||||
// This allows HLSL legalization regarding resources.
|
||||
val_opts.SetRelaxLogicalPointer(true);
|
||||
// This uses relaxed rules for pre-legalized HLSL.
|
||||
val_opts.SetBeforeHlslLegalization(true);
|
||||
|
||||
spvtools::OptimizerOptions opt_opts;
|
||||
opt_opts.set_validator_options(val_opts);
|
||||
opt_opts.set_run_validator(true);
|
||||
|
||||
spvtools::Optimizer optimizer(GetSpirvToolsTargetEnv(env, version));
|
||||
|
||||
std::ostringstream oss;
|
||||
optimizer.SetMessageConsumer(
|
||||
[&oss](spv_message_level_t, const char*, const spv_position_t&,
|
||||
const char* message) { oss << message << "\n"; });
|
||||
|
||||
for (const auto& pass : enabled_passes) {
|
||||
switch (pass) {
|
||||
case PassId::kLegalizationPasses:
|
||||
optimizer.RegisterLegalizationPasses();
|
||||
break;
|
||||
case PassId::kPerformancePasses:
|
||||
optimizer.RegisterPerformancePasses();
|
||||
break;
|
||||
case PassId::kSizePasses:
|
||||
optimizer.RegisterSizePasses();
|
||||
break;
|
||||
case PassId::kNullPass:
|
||||
// We actually don't need to do anything for null pass.
|
||||
break;
|
||||
case PassId::kStripDebugInfo:
|
||||
optimizer.RegisterPass(spvtools::CreateStripDebugInfoPass());
|
||||
break;
|
||||
case PassId::kCompactIds:
|
||||
optimizer.RegisterPass(spvtools::CreateCompactIdsPass());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!optimizer.Run(binary->data(), binary->size(), binary, opt_opts)) {
|
||||
*errors = oss.str();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace shaderc_util
|
||||
59
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/src/version_profile.cc
vendored
Normal file
59
Android/android-ndk-r27d/sources/third_party/shaderc/libshaderc_util/src/version_profile.cc
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
// 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 "libshaderc_util/version_profile.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <sstream>
|
||||
|
||||
namespace {
|
||||
|
||||
const int kVersionNumberLength = 3;
|
||||
const int kMaxProfileLength = 13; // strlen(compatibility)
|
||||
const int kMaxVersionProfileLength = kVersionNumberLength + kMaxProfileLength;
|
||||
const int kMinVersionProfileLength = kVersionNumberLength;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace shaderc_util {
|
||||
|
||||
bool ParseVersionProfile(const std::string& version_profile, int* version,
|
||||
EProfile* profile) {
|
||||
if (version_profile.size() < kMinVersionProfileLength ||
|
||||
version_profile.size() > kMaxVersionProfileLength ||
|
||||
!::isdigit(version_profile.front()))
|
||||
return false;
|
||||
|
||||
std::string profile_string;
|
||||
std::istringstream(version_profile) >> *version >> profile_string;
|
||||
|
||||
if (!IsKnownVersion(*version)) {
|
||||
return false;
|
||||
}
|
||||
if (profile_string.empty()) {
|
||||
*profile = ENoProfile;
|
||||
} else if (profile_string == "core") {
|
||||
*profile = ECoreProfile;
|
||||
} else if (profile_string == "es") {
|
||||
*profile = EEsProfile;
|
||||
} else if (profile_string == "compatibility") {
|
||||
*profile = ECompatibilityProfile;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace shaderc_util
|
||||
Reference in New Issue
Block a user