Merge pull request #85 from godlikepanos/master

Add the option to build without exceptions
This commit is contained in:
Hans-Kristian Arntzen 2016-12-19 12:32:04 +01:00 коммит произвёл GitHub
Родитель 2f48065ec1 7f69f9395e
Коммит 9ccd1aea42
10 изменённых файлов: 206 добавлений и 149 удалений

Просмотреть файл

@ -16,6 +16,8 @@ cmake_minimum_required(VERSION 2.8)
project(SPIRV-Cross) project(SPIRV-Cross)
enable_testing() enable_testing()
option(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS "Instead of throwing exceptions assert" OFF)
if(${CMAKE_GENERATOR} MATCHES "Makefile") if(${CMAKE_GENERATOR} MATCHES "Makefile")
if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
message(FATAL_ERROR "Build out of tree to avoid overwriting Makefile") message(FATAL_ERROR "Build out of tree to avoid overwriting Makefile")
@ -50,24 +52,35 @@ target_link_libraries(spirv-cross-msl spirv-cross-glsl)
target_link_libraries(spirv-cross-cpp spirv-cross-glsl) target_link_libraries(spirv-cross-cpp spirv-cross-glsl)
target_include_directories(spirv-cross-core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(spirv-cross-core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
set(spirv-compiler-options "")
set(spirv-compiler-defines "")
if(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS)
set(spirv-compiler-defines ${spirv-compiler-defines} SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS)
endif()
# To specify special debug or optimization options, use # To specify special debug or optimization options, use
# -DCMAKE_CXX_COMPILE_FLAGS # -DCMAKE_CXX_COMPILE_FLAGS
# However, we require the C++11 dialect. # However, we require the C++11 dialect.
if (NOT "${MSVC}") if (NOT "${MSVC}")
set(spirv-compiler-options -std=c++11 -Wall -Wextra -Werror -Wshadow) set(spirv-compiler-options ${spirv-compiler-options} -std=c++11 -Wall -Wextra -Werror -Wshadow)
set(spirv-compiler-defines __STDC_LIMIT_MACROS) set(spirv-compiler-defines ${spirv-compiler-defines} __STDC_LIMIT_MACROS)
target_compile_options(spirv-cross-core PRIVATE ${spirv-compiler-options})
target_compile_options(spirv-cross-glsl PRIVATE ${spirv-compiler-options})
target_compile_options(spirv-cross-msl PRIVATE ${spirv-compiler-options})
target_compile_options(spirv-cross-cpp PRIVATE ${spirv-compiler-options})
target_compile_options(spirv-cross PRIVATE ${spirv-compiler-options})
target_compile_definitions(spirv-cross-core PRIVATE ${spirv-compiler-defines})
target_compile_definitions(spirv-cross-glsl PRIVATE ${spirv-compiler-defines})
target_compile_definitions(spirv-cross-msl PRIVATE ${spirv-compiler-defines})
target_compile_definitions(spirv-cross-cpp PRIVATE ${spirv-compiler-defines})
target_compile_definitions(spirv-cross PRIVATE ${spirv-compiler-defines})
endif(NOT "${MSVC}")
if(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS)
set(spirv-compiler-options ${spirv-compiler-options} -fno-exceptions)
endif()
endif()
target_compile_options(spirv-cross-core PRIVATE ${spirv-compiler-options})
target_compile_options(spirv-cross-glsl PRIVATE ${spirv-compiler-options})
target_compile_options(spirv-cross-msl PRIVATE ${spirv-compiler-options})
target_compile_options(spirv-cross-cpp PRIVATE ${spirv-compiler-options})
target_compile_options(spirv-cross PRIVATE ${spirv-compiler-options})
target_compile_definitions(spirv-cross-core PRIVATE ${spirv-compiler-defines})
target_compile_definitions(spirv-cross-glsl PRIVATE ${spirv-compiler-defines})
target_compile_definitions(spirv-cross-msl PRIVATE ${spirv-compiler-defines})
target_compile_definitions(spirv-cross-cpp PRIVATE ${spirv-compiler-defines})
target_compile_definitions(spirv-cross PRIVATE ${spirv-compiler-defines})
# Set up tests, using only the simplest modes of the test_shaders # Set up tests, using only the simplest modes of the test_shaders
# script. You have to invoke the script manually to: # script. You have to invoke the script manually to:
@ -80,5 +93,6 @@ if(${PYTHONINTERP_FOUND} AND ${PYTHON_VERSION_MAJOR} GREATER 2)
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py
${CMAKE_CURRENT_SOURCE_DIR}/shaders) ${CMAKE_CURRENT_SOURCE_DIR}/shaders)
else() else()
message(WARNING "Testing disabled. Could not find python3") message(WARNING "Testing disabled. Could not find python3. If you have python3 installed try running "
"cmake with -DPYTHON_EXECUTABLE:FILEPATH=/path/to/python3 to help it find the executable")
endif() endif()

Просмотреть файл

@ -15,7 +15,11 @@ CXXFLAGS += -std=c++11 -Wall -Wextra -Wshadow -D__STDC_LIMIT_MACROS
ifeq ($(DEBUG), 1) ifeq ($(DEBUG), 1)
CXXFLAGS += -O0 -g CXXFLAGS += -O0 -g
else else
CXXFLAGS += -O2 -g CXXFLAGS += -O2 -DNDEBUG
endif
ifeq ($(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS), 1)
CXXFLAGS += -DSPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS -fno-exceptions
endif endif
all: $(TARGET) all: $(TARGET)

Просмотреть файл

@ -23,6 +23,8 @@ However, most missing features are expected to be "trivial" improvements at this
SPIRV-Cross has been tested on Linux, OSX and Windows. SPIRV-Cross has been tested on Linux, OSX and Windows.
The make and CMake build flavors offer the option to treat exceptions as assertions. To disable exceptions for make just append SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS=1 to the command line. For CMake append -DSPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS=ON. By default exceptions are enabled.
### Linux and macOS ### Linux and macOS
Just run `make` on the command line. A recent GCC (4.8+) or Clang (3.x+) compiler is required as SPIRV-Cross uses C++11 extensively. Just run `make` on the command line. A recent GCC (4.8+) or Clang (3.x+) compiler is required as SPIRV-Cross uses C++11 extensively.

Просмотреть файл

@ -30,6 +30,17 @@ using namespace spv;
using namespace spirv_cross; using namespace spirv_cross;
using namespace std; using namespace std;
#ifdef SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
#define THROW(x) \
do \
{ \
fprintf(stderr, "%s.", x); \
exit(1); \
} while (0)
#else
#define THROW(x) runtime_error(x)
#endif
struct CLIParser; struct CLIParser;
struct CLICallbacks struct CLICallbacks
{ {
@ -53,7 +64,9 @@ struct CLIParser
bool parse() bool parse()
{ {
#ifndef SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
try try
#endif
{ {
while (argc && !ended_state) while (argc && !ended_state)
{ {
@ -69,7 +82,7 @@ struct CLIParser
auto itr = cbs.callbacks.find(next); auto itr = cbs.callbacks.find(next);
if (itr == ::end(cbs.callbacks)) if (itr == ::end(cbs.callbacks))
{ {
throw logic_error("Invalid argument.\n"); THROW("Invalid argument");
} }
itr->second(*this); itr->second(*this);
@ -78,6 +91,7 @@ struct CLIParser
return true; return true;
} }
#ifndef SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
catch (...) catch (...)
{ {
if (cbs.error_handler) if (cbs.error_handler)
@ -86,6 +100,7 @@ struct CLIParser
} }
return false; return false;
} }
#endif
} }
void end() void end()
@ -97,13 +112,13 @@ struct CLIParser
{ {
if (!argc) if (!argc)
{ {
throw logic_error("Tried to parse uint, but nothing left in arguments.\n"); THROW("Tried to parse uint, but nothing left in arguments");
} }
uint32_t val = stoul(*argv); uint32_t val = stoul(*argv);
if (val > numeric_limits<uint32_t>::max()) if (val > numeric_limits<uint32_t>::max())
{ {
throw out_of_range("next_uint() out of range.\n"); THROW("next_uint() out of range");
} }
argc--; argc--;
@ -116,7 +131,7 @@ struct CLIParser
{ {
if (!argc) if (!argc)
{ {
throw logic_error("Tried to parse double, but nothing left in arguments.\n"); THROW("Tried to parse double, but nothing left in arguments");
} }
double val = stod(*argv); double val = stod(*argv);
@ -131,7 +146,7 @@ struct CLIParser
{ {
if (!argc) if (!argc)
{ {
throw logic_error("Tried to parse string, but nothing left in arguments.\n"); THROW("Tried to parse string, but nothing left in arguments");
} }
const char *ret = *argv; const char *ret = *argv;

Просмотреть файл

@ -17,13 +17,31 @@
#ifndef SPIRV_CROSS_COMMON_HPP #ifndef SPIRV_CROSS_COMMON_HPP
#define SPIRV_CROSS_COMMON_HPP #define SPIRV_CROSS_COMMON_HPP
#include <cstdio>
#include <cstring>
#include <functional> #include <functional>
#include <sstream> #include <sstream>
#include <stdio.h>
#include <string.h>
namespace spirv_cross namespace spirv_cross
{ {
#ifdef SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
#ifndef _MSC_VER
[[noreturn]]
#endif
inline void
report_and_abort(const std::string &msg)
{
#ifdef NDEBUG
(void)msg;
#else
fprintf(stderr, "There was a compiler error: %s\n", msg.c_str());
#endif
abort();
}
#define SPIRV_CROSS_THROW(x) report_and_abort(x)
#else
class CompilerError : public std::runtime_error class CompilerError : public std::runtime_error
{ {
public: public:
@ -33,6 +51,9 @@ public:
} }
}; };
#define SPIRV_CROSS_THROW(x) throw CompilerError(x)
#endif
namespace inner namespace inner
{ {
template <typename T> template <typename T>
@ -792,7 +813,7 @@ public:
{ {
holder = std::move(val); holder = std::move(val);
if (type != TypeNone && type != new_type) if (type != TypeNone && type != new_type)
throw CompilerError("Overwriting a variant with new type."); SPIRV_CROSS_THROW("Overwriting a variant with new type.");
type = new_type; type = new_type;
} }
@ -800,9 +821,9 @@ public:
T &get() T &get()
{ {
if (!holder) if (!holder)
throw CompilerError("nullptr"); SPIRV_CROSS_THROW("nullptr");
if (T::type != type) if (T::type != type)
throw CompilerError("Bad cast"); SPIRV_CROSS_THROW("Bad cast");
return *static_cast<T *>(holder.get()); return *static_cast<T *>(holder.get());
} }
@ -810,9 +831,9 @@ public:
const T &get() const const T &get() const
{ {
if (!holder) if (!holder)
throw CompilerError("nullptr"); SPIRV_CROSS_THROW("nullptr");
if (T::type != type) if (T::type != type)
throw CompilerError("Bad cast"); SPIRV_CROSS_THROW("Bad cast");
return *static_cast<const T *>(holder.get()); return *static_cast<const T *>(holder.get());
} }

Просмотреть файл

@ -116,8 +116,8 @@ void CompilerCPP::emit_push_constant_block(const SPIRVariable &var)
auto &type = get<SPIRType>(var.basetype); auto &type = get<SPIRType>(var.basetype);
auto &flags = meta[var.self].decoration.decoration_flags; auto &flags = meta[var.self].decoration.decoration_flags;
if ((flags & (1ull << DecorationBinding)) || (flags & (1ull << DecorationDescriptorSet))) if ((flags & (1ull << DecorationBinding)) || (flags & (1ull << DecorationDescriptorSet)))
throw CompilerError("Push constant blocks cannot be compiled to GLSL with Binding or Set syntax. " SPIRV_CROSS_THROW("Push constant blocks cannot be compiled to GLSL with Binding or Set syntax. "
"Remap to location with reflection API first or disable these decorations."); "Remap to location with reflection API first or disable these decorations.");
emit_block_struct(type); emit_block_struct(type);
auto buffer_name = to_name(type.self); auto buffer_name = to_name(type.self);
@ -298,7 +298,7 @@ string CompilerCPP::compile()
do do
{ {
if (pass_count >= 3) if (pass_count >= 3)
throw CompilerError("Over 3 compilation loops detected. Must be a bug!"); SPIRV_CROSS_THROW("Over 3 compilation loops detected. Must be a bug!");
resource_registrations.clear(); resource_registrations.clear();
reset(); reset();
@ -469,7 +469,7 @@ void CompilerCPP::emit_header()
break; break;
default: default:
throw CompilerError("Unsupported execution model."); SPIRV_CROSS_THROW("Unsupported execution model.");
} }
switch (execution.model) switch (execution.model)
@ -506,6 +506,6 @@ void CompilerCPP::emit_header()
break; break;
default: default:
throw CompilerError("Unsupported execution model."); SPIRV_CROSS_THROW("Unsupported execution model.");
} }
} }

Просмотреть файл

@ -33,7 +33,7 @@ Instruction::Instruction(const vector<uint32_t> &spirv, uint32_t &index)
count = (spirv[index] >> 16) & 0xffff; count = (spirv[index] >> 16) & 0xffff;
if (count == 0) if (count == 0)
throw CompilerError("SPIR-V instructions cannot consume 0 words. Invalid SPIR-V file."); SPIRV_CROSS_THROW("SPIR-V instructions cannot consume 0 words. Invalid SPIR-V file.");
offset = index + 1; offset = index + 1;
length = count - 1; length = count - 1;
@ -41,7 +41,7 @@ Instruction::Instruction(const vector<uint32_t> &spirv, uint32_t &index)
index += count; index += count;
if (index > spirv.size()) if (index > spirv.size())
throw CompilerError("SPIR-V instruction goes out of bounds."); SPIRV_CROSS_THROW("SPIR-V instruction goes out of bounds.");
} }
Compiler::Compiler(vector<uint32_t> ir) Compiler::Compiler(vector<uint32_t> ir)
@ -328,7 +328,7 @@ const SPIRType &Compiler::expression_type(uint32_t id) const
return get<SPIRType>(get<SPIRUndef>(id).basetype); return get<SPIRType>(get<SPIRUndef>(id).basetype);
default: default:
throw CompilerError("Cannot resolve expression type."); SPIRV_CROSS_THROW("Cannot resolve expression type.");
} }
} }
@ -665,7 +665,7 @@ static string extract_string(const vector<uint32_t> &spirv, uint32_t offset)
} }
} }
throw CompilerError("String was not terminated before EOF"); SPIRV_CROSS_THROW("String was not terminated before EOF");
} }
static bool is_valid_spirv_version(uint32_t version) static bool is_valid_spirv_version(uint32_t version)
@ -687,7 +687,7 @@ void Compiler::parse()
{ {
auto len = spirv.size(); auto len = spirv.size();
if (len < 5) if (len < 5)
throw CompilerError("SPIRV file too small."); SPIRV_CROSS_THROW("SPIRV file too small.");
auto s = spirv.data(); auto s = spirv.data();
@ -696,7 +696,7 @@ void Compiler::parse()
transform(begin(spirv), end(spirv), begin(spirv), [](uint32_t c) { return swap_endian(c); }); transform(begin(spirv), end(spirv), begin(spirv), [](uint32_t c) { return swap_endian(c); });
if (s[0] != MagicNumber || !is_valid_spirv_version(s[1])) if (s[0] != MagicNumber || !is_valid_spirv_version(s[1]))
throw CompilerError("Invalid SPIRV format."); SPIRV_CROSS_THROW("Invalid SPIRV format.");
uint32_t bound = s[3]; uint32_t bound = s[3];
ids.resize(bound); ids.resize(bound);
@ -710,9 +710,9 @@ void Compiler::parse()
parse(i); parse(i);
if (current_function) if (current_function)
throw CompilerError("Function was not terminated."); SPIRV_CROSS_THROW("Function was not terminated.");
if (current_block) if (current_block)
throw CompilerError("Block was not terminated."); SPIRV_CROSS_THROW("Block was not terminated.");
} }
void Compiler::flatten_interface_block(uint32_t id) void Compiler::flatten_interface_block(uint32_t id)
@ -722,24 +722,24 @@ void Compiler::flatten_interface_block(uint32_t id)
auto flags = meta.at(type.self).decoration.decoration_flags; auto flags = meta.at(type.self).decoration.decoration_flags;
if (!type.array.empty()) if (!type.array.empty())
throw CompilerError("Type is array of UBOs."); SPIRV_CROSS_THROW("Type is array of UBOs.");
if (type.basetype != SPIRType::Struct) if (type.basetype != SPIRType::Struct)
throw CompilerError("Type is not a struct."); SPIRV_CROSS_THROW("Type is not a struct.");
if ((flags & (1ull << DecorationBlock)) == 0) if ((flags & (1ull << DecorationBlock)) == 0)
throw CompilerError("Type is not a block."); SPIRV_CROSS_THROW("Type is not a block.");
if (type.member_types.empty()) if (type.member_types.empty())
throw CompilerError("Member list of struct is empty."); SPIRV_CROSS_THROW("Member list of struct is empty.");
uint32_t t = type.member_types[0]; uint32_t t = type.member_types[0];
for (auto &m : type.member_types) for (auto &m : type.member_types)
if (t != m) if (t != m)
throw CompilerError("Types in block differ."); SPIRV_CROSS_THROW("Types in block differ.");
auto &mtype = get<SPIRType>(t); auto &mtype = get<SPIRType>(t);
if (!mtype.array.empty()) if (!mtype.array.empty())
throw CompilerError("Member type cannot be arrays."); SPIRV_CROSS_THROW("Member type cannot be arrays.");
if (mtype.basetype == SPIRType::Struct) if (mtype.basetype == SPIRType::Struct)
throw CompilerError("Member type cannot be struct."); SPIRV_CROSS_THROW("Member type cannot be struct.");
// Inherit variable name from interface block name. // Inherit variable name from interface block name.
meta.at(var.self).decoration.alias = meta.at(type.self).decoration.alias; meta.at(var.self).decoration.alias = meta.at(type.self).decoration.alias;
@ -1112,7 +1112,7 @@ void Compiler::parse(const Instruction &instruction)
{ {
uint32_t cap = ops[0]; uint32_t cap = ops[0];
if (cap == CapabilityKernel) if (cap == CapabilityKernel)
throw CompilerError("Kernel capability not supported."); SPIRV_CROSS_THROW("Kernel capability not supported.");
break; break;
} }
@ -1123,7 +1123,7 @@ void Compiler::parse(const Instruction &instruction)
if (ext == "GLSL.std.450") if (ext == "GLSL.std.450")
set<SPIRExtension>(id, SPIRExtension::GLSL); set<SPIRExtension>(id, SPIRExtension::GLSL);
else else
throw CompilerError("Only GLSL.std.450 extension interface supported."); SPIRV_CROSS_THROW("Only GLSL.std.450 extension interface supported.");
break; break;
} }
@ -1362,7 +1362,7 @@ void Compiler::parse(const Instruction &instruction)
ptrbase = base; ptrbase = base;
if (ptrbase.pointer) if (ptrbase.pointer)
throw CompilerError("Cannot make pointer-to-pointer type."); SPIRV_CROSS_THROW("Cannot make pointer-to-pointer type.");
ptrbase.pointer = true; ptrbase.pointer = true;
ptrbase.storage = static_cast<StorageClass>(ops[1]); ptrbase.storage = static_cast<StorageClass>(ops[1]);
@ -1425,7 +1425,7 @@ void Compiler::parse(const Instruction &instruction)
if (storage == StorageClassFunction) if (storage == StorageClassFunction)
{ {
if (!current_function) if (!current_function)
throw CompilerError("No function currently in scope"); SPIRV_CROSS_THROW("No function currently in scope");
current_function->add_local_variable(id); current_function->add_local_variable(id);
} }
else if (storage == StorageClassPrivate || storage == StorageClassWorkgroup || storage == StorageClassOutput) else if (storage == StorageClassPrivate || storage == StorageClassWorkgroup || storage == StorageClassOutput)
@ -1460,9 +1460,9 @@ void Compiler::parse(const Instruction &instruction)
case OpPhi: case OpPhi:
{ {
if (!current_function) if (!current_function)
throw CompilerError("No function currently in scope"); SPIRV_CROSS_THROW("No function currently in scope");
if (!current_block) if (!current_block)
throw CompilerError("No block currently in scope"); SPIRV_CROSS_THROW("No block currently in scope");
uint32_t result_type = ops[0]; uint32_t result_type = ops[0];
uint32_t id = ops[1]; uint32_t id = ops[1];
@ -1554,7 +1554,7 @@ void Compiler::parse(const Instruction &instruction)
break; break;
default: default:
throw CompilerError("OpConstantComposite only supports 1, 2, 3 and 4 columns."); SPIRV_CROSS_THROW("OpConstantComposite only supports 1, 2, 3 and 4 columns.");
} }
} }
else else
@ -1612,7 +1612,7 @@ void Compiler::parse(const Instruction &instruction)
break; break;
default: default:
throw CompilerError("OpConstantComposite only supports 1, 2, 3 and 4 components."); SPIRV_CROSS_THROW("OpConstantComposite only supports 1, 2, 3 and 4 components.");
} }
} }
@ -1629,7 +1629,7 @@ void Compiler::parse(const Instruction &instruction)
uint32_t type = ops[3]; uint32_t type = ops[3];
if (current_function) if (current_function)
throw CompilerError("Must end a function before starting a new one!"); SPIRV_CROSS_THROW("Must end a function before starting a new one!");
current_function = &set<SPIRFunction>(id, res, type); current_function = &set<SPIRFunction>(id, res, type);
break; break;
@ -1641,7 +1641,7 @@ void Compiler::parse(const Instruction &instruction)
uint32_t id = ops[1]; uint32_t id = ops[1];
if (!current_function) if (!current_function)
throw CompilerError("Must be in a function!"); SPIRV_CROSS_THROW("Must be in a function!");
current_function->add_parameter(type, id); current_function->add_parameter(type, id);
set<SPIRVariable>(id, type, StorageClassFunction); set<SPIRVariable>(id, type, StorageClassFunction);
@ -1653,7 +1653,7 @@ void Compiler::parse(const Instruction &instruction)
if (current_block) if (current_block)
{ {
// Very specific error message, but seems to come up quite often. // Very specific error message, but seems to come up quite often.
throw CompilerError( SPIRV_CROSS_THROW(
"Cannot end a function before ending the current block.\n" "Cannot end a function before ending the current block.\n"
"Likely cause: If this SPIR-V was created from glslang HLSL, make sure the entry point is valid."); "Likely cause: If this SPIR-V was created from glslang HLSL, make sure the entry point is valid.");
} }
@ -1666,7 +1666,7 @@ void Compiler::parse(const Instruction &instruction)
{ {
// OpLabel always starts a block. // OpLabel always starts a block.
if (!current_function) if (!current_function)
throw CompilerError("Blocks cannot exist outside functions!"); SPIRV_CROSS_THROW("Blocks cannot exist outside functions!");
uint32_t id = ops[0]; uint32_t id = ops[0];
@ -1675,7 +1675,7 @@ void Compiler::parse(const Instruction &instruction)
current_function->entry_block = id; current_function->entry_block = id;
if (current_block) if (current_block)
throw CompilerError("Cannot start a block before ending the current block."); SPIRV_CROSS_THROW("Cannot start a block before ending the current block.");
current_block = &set<SPIRBlock>(id); current_block = &set<SPIRBlock>(id);
break; break;
@ -1685,7 +1685,7 @@ void Compiler::parse(const Instruction &instruction)
case OpBranch: case OpBranch:
{ {
if (!current_block) if (!current_block)
throw CompilerError("Trying to end a non-existing block."); SPIRV_CROSS_THROW("Trying to end a non-existing block.");
uint32_t target = ops[0]; uint32_t target = ops[0];
current_block->terminator = SPIRBlock::Direct; current_block->terminator = SPIRBlock::Direct;
@ -1697,7 +1697,7 @@ void Compiler::parse(const Instruction &instruction)
case OpBranchConditional: case OpBranchConditional:
{ {
if (!current_block) if (!current_block)
throw CompilerError("Trying to end a non-existing block."); SPIRV_CROSS_THROW("Trying to end a non-existing block.");
current_block->condition = ops[0]; current_block->condition = ops[0];
current_block->true_block = ops[1]; current_block->true_block = ops[1];
@ -1711,10 +1711,10 @@ void Compiler::parse(const Instruction &instruction)
case OpSwitch: case OpSwitch:
{ {
if (!current_block) if (!current_block)
throw CompilerError("Trying to end a non-existing block."); SPIRV_CROSS_THROW("Trying to end a non-existing block.");
if (current_block->merge == SPIRBlock::MergeNone) if (current_block->merge == SPIRBlock::MergeNone)
throw CompilerError("Switch statement is not structured"); SPIRV_CROSS_THROW("Switch statement is not structured");
current_block->terminator = SPIRBlock::MultiSelect; current_block->terminator = SPIRBlock::MultiSelect;
@ -1734,7 +1734,7 @@ void Compiler::parse(const Instruction &instruction)
case OpKill: case OpKill:
{ {
if (!current_block) if (!current_block)
throw CompilerError("Trying to end a non-existing block."); SPIRV_CROSS_THROW("Trying to end a non-existing block.");
current_block->terminator = SPIRBlock::Kill; current_block->terminator = SPIRBlock::Kill;
current_block = nullptr; current_block = nullptr;
break; break;
@ -1743,7 +1743,7 @@ void Compiler::parse(const Instruction &instruction)
case OpReturn: case OpReturn:
{ {
if (!current_block) if (!current_block)
throw CompilerError("Trying to end a non-existing block."); SPIRV_CROSS_THROW("Trying to end a non-existing block.");
current_block->terminator = SPIRBlock::Return; current_block->terminator = SPIRBlock::Return;
current_block = nullptr; current_block = nullptr;
break; break;
@ -1752,7 +1752,7 @@ void Compiler::parse(const Instruction &instruction)
case OpReturnValue: case OpReturnValue:
{ {
if (!current_block) if (!current_block)
throw CompilerError("Trying to end a non-existing block."); SPIRV_CROSS_THROW("Trying to end a non-existing block.");
current_block->terminator = SPIRBlock::Return; current_block->terminator = SPIRBlock::Return;
current_block->return_value = ops[0]; current_block->return_value = ops[0];
current_block = nullptr; current_block = nullptr;
@ -1762,7 +1762,7 @@ void Compiler::parse(const Instruction &instruction)
case OpUnreachable: case OpUnreachable:
{ {
if (!current_block) if (!current_block)
throw CompilerError("Trying to end a non-existing block."); SPIRV_CROSS_THROW("Trying to end a non-existing block.");
current_block->terminator = SPIRBlock::Unreachable; current_block->terminator = SPIRBlock::Unreachable;
current_block = nullptr; current_block = nullptr;
break; break;
@ -1771,7 +1771,7 @@ void Compiler::parse(const Instruction &instruction)
case OpSelectionMerge: case OpSelectionMerge:
{ {
if (!current_block) if (!current_block)
throw CompilerError("Trying to modify a non-existing block."); SPIRV_CROSS_THROW("Trying to modify a non-existing block.");
current_block->next_block = ops[0]; current_block->next_block = ops[0];
current_block->merge = SPIRBlock::MergeSelection; current_block->merge = SPIRBlock::MergeSelection;
@ -1782,7 +1782,7 @@ void Compiler::parse(const Instruction &instruction)
case OpLoopMerge: case OpLoopMerge:
{ {
if (!current_block) if (!current_block)
throw CompilerError("Trying to modify a non-existing block."); SPIRV_CROSS_THROW("Trying to modify a non-existing block.");
current_block->merge_block = ops[0]; current_block->merge_block = ops[0];
current_block->continue_block = ops[1]; current_block->continue_block = ops[1];
@ -1802,7 +1802,7 @@ void Compiler::parse(const Instruction &instruction)
case OpSpecConstantOp: case OpSpecConstantOp:
{ {
if (length < 3) if (length < 3)
throw CompilerError("OpSpecConstantOp not enough arguments."); SPIRV_CROSS_THROW("OpSpecConstantOp not enough arguments.");
uint32_t result_type = ops[0]; uint32_t result_type = ops[0];
uint32_t id = ops[1]; uint32_t id = ops[1];
@ -1816,7 +1816,7 @@ void Compiler::parse(const Instruction &instruction)
default: default:
{ {
if (!current_block) if (!current_block)
throw CompilerError("Currently no block to insert opcode."); SPIRV_CROSS_THROW("Currently no block to insert opcode.");
current_block->ops.push_back(instruction); current_block->ops.push_back(instruction);
break; break;
@ -2040,7 +2040,7 @@ uint32_t Compiler::type_struct_member_offset(const SPIRType &type, uint32_t inde
if (dec.decoration_flags & (1ull << DecorationOffset)) if (dec.decoration_flags & (1ull << DecorationOffset))
return dec.offset; return dec.offset;
else else
throw CompilerError("Struct member does not have Offset set."); SPIRV_CROSS_THROW("Struct member does not have Offset set.");
} }
uint32_t Compiler::type_struct_member_array_stride(const SPIRType &type, uint32_t index) const uint32_t Compiler::type_struct_member_array_stride(const SPIRType &type, uint32_t index) const
@ -2051,7 +2051,7 @@ uint32_t Compiler::type_struct_member_array_stride(const SPIRType &type, uint32_
if (dec.decoration_flags & (1ull << DecorationArrayStride)) if (dec.decoration_flags & (1ull << DecorationArrayStride))
return dec.array_stride; return dec.array_stride;
else else
throw CompilerError("Struct member does not have ArrayStride set."); SPIRV_CROSS_THROW("Struct member does not have ArrayStride set.");
} }
size_t Compiler::get_declared_struct_size(const SPIRType &type) const size_t Compiler::get_declared_struct_size(const SPIRType &type) const
@ -2078,7 +2078,7 @@ size_t Compiler::get_declared_struct_member_size(const SPIRType &struct_type, ui
case SPIRType::Image: case SPIRType::Image:
case SPIRType::SampledImage: case SPIRType::SampledImage:
case SPIRType::Sampler: case SPIRType::Sampler:
throw CompilerError("Querying size for object with opaque size.\n"); SPIRV_CROSS_THROW("Querying size for object with opaque size.\n");
default: default:
break; break;
@ -2357,7 +2357,7 @@ SPIREntryPoint &Compiler::get_entry_point(const std::string &name)
[&](const std::pair<uint32_t, SPIREntryPoint> &entry) -> bool { return entry.second.name == name; }); [&](const std::pair<uint32_t, SPIREntryPoint> &entry) -> bool { return entry.second.name == name; });
if (itr == end(entry_points)) if (itr == end(entry_points))
throw CompilerError("Entry point does not exist."); SPIRV_CROSS_THROW("Entry point does not exist.");
return itr->second; return itr->second;
} }
@ -2369,7 +2369,7 @@ const SPIREntryPoint &Compiler::get_entry_point(const std::string &name) const
[&](const std::pair<uint32_t, SPIREntryPoint> &entry) -> bool { return entry.second.name == name; }); [&](const std::pair<uint32_t, SPIREntryPoint> &entry) -> bool { return entry.second.name == name; });
if (itr == end(entry_points)) if (itr == end(entry_points))
throw CompilerError("Entry point does not exist."); SPIRV_CROSS_THROW("Entry point does not exist.");
return itr->second; return itr->second;
} }
@ -2388,7 +2388,7 @@ bool Compiler::interface_variable_exists_in_entry_point(uint32_t id) const
{ {
auto &var = get<SPIRVariable>(id); auto &var = get<SPIRVariable>(id);
if (var.storage != StorageClassInput && var.storage != StorageClassOutput) if (var.storage != StorageClassInput && var.storage != StorageClassOutput)
throw CompilerError("Only Input and Output variables are part of a shader linking interface."); SPIRV_CROSS_THROW("Only Input and Output variables are part of a shader linking interface.");
// This is to avoid potential problems with very old glslang versions which did // This is to avoid potential problems with very old glslang versions which did
// not emit input/output interfaces properly. // not emit input/output interfaces properly.
@ -2613,11 +2613,11 @@ bool Compiler::CombinedImageSamplerHandler::handle(Op opcode, const uint32_t *ar
bool separate_image = type.basetype == SPIRType::Image && type.image.sampled == 1; bool separate_image = type.basetype == SPIRType::Image && type.image.sampled == 1;
bool separate_sampler = type.basetype == SPIRType::Sampler; bool separate_sampler = type.basetype == SPIRType::Sampler;
if (separate_image) if (separate_image)
throw CompilerError( SPIRV_CROSS_THROW(
"Attempting to use arrays of separate images. This is not possible to statically remap to plain GLSL."); "Attempting to use arrays of separate images. This is not possible to statically remap to plain GLSL.");
if (separate_sampler) if (separate_sampler)
throw CompilerError("Attempting to use arrays of separate samplers. This is not possible to statically " SPIRV_CROSS_THROW("Attempting to use arrays of separate samplers. This is not possible to statically "
"remap to plain GLSL."); "remap to plain GLSL.");
return true; return true;
} }

Просмотреть файл

@ -327,7 +327,7 @@ protected:
return nullptr; return nullptr;
if (instr.offset + instr.length > spirv.size()) if (instr.offset + instr.length > spirv.size())
throw CompilerError("Compiler::stream() out of range."); SPIRV_CROSS_THROW("Compiler::stream() out of range.");
return &spirv[instr.offset]; return &spirv[instr.offset];
} }
std::vector<uint32_t> spirv; std::vector<uint32_t> spirv;

Просмотреть файл

@ -184,7 +184,7 @@ void CompilerGLSL::remap_pls_variables()
} }
if (var.storage != StorageClassInput && !input_is_target) if (var.storage != StorageClassInput && !input_is_target)
throw CompilerError("Can only use in and target variables for PLS inputs."); SPIRV_CROSS_THROW("Can only use in and target variables for PLS inputs.");
var.remapped_variable = true; var.remapped_variable = true;
} }
@ -192,7 +192,7 @@ void CompilerGLSL::remap_pls_variables()
{ {
auto &var = get<SPIRVariable>(output.id); auto &var = get<SPIRVariable>(output.id);
if (var.storage != StorageClassOutput) if (var.storage != StorageClassOutput)
throw CompilerError("Can only use out variables for PLS outputs."); SPIRV_CROSS_THROW("Can only use out variables for PLS outputs.");
var.remapped_variable = true; var.remapped_variable = true;
} }
} }
@ -207,7 +207,7 @@ void CompilerGLSL::find_static_extensions()
if (type.basetype == SPIRType::Double) if (type.basetype == SPIRType::Double)
{ {
if (options.es) if (options.es)
throw CompilerError("FP64 not supported in ES profile."); SPIRV_CROSS_THROW("FP64 not supported in ES profile.");
if (!options.es && options.version < 400) if (!options.es && options.version < 400)
require_extension("GL_ARB_gpu_shader_fp64"); require_extension("GL_ARB_gpu_shader_fp64");
} }
@ -215,7 +215,7 @@ void CompilerGLSL::find_static_extensions()
if (type.basetype == SPIRType::Int64 || type.basetype == SPIRType::UInt64) if (type.basetype == SPIRType::Int64 || type.basetype == SPIRType::UInt64)
{ {
if (options.es) if (options.es)
throw CompilerError("64-bit integers not supported in ES profile."); SPIRV_CROSS_THROW("64-bit integers not supported in ES profile.");
if (!options.es) if (!options.es)
require_extension("GL_ARB_gpu_shader_int64"); require_extension("GL_ARB_gpu_shader_int64");
} }
@ -229,7 +229,7 @@ void CompilerGLSL::find_static_extensions()
if (!options.es && options.version < 430) if (!options.es && options.version < 430)
require_extension("GL_ARB_compute_shader"); require_extension("GL_ARB_compute_shader");
if (options.es && options.version < 310) if (options.es && options.version < 310)
throw CompilerError("At least ESSL 3.10 required for compute shaders."); SPIRV_CROSS_THROW("At least ESSL 3.10 required for compute shaders.");
break; break;
case ExecutionModelGeometry: case ExecutionModelGeometry:
@ -271,7 +271,7 @@ string CompilerGLSL::compile()
do do
{ {
if (pass_count >= 3) if (pass_count >= 3)
throw CompilerError("Over 3 compilation loops detected. Must be a bug!"); SPIRV_CROSS_THROW("Over 3 compilation loops detected. Must be a bug!");
reset(); reset();
@ -561,7 +561,7 @@ const char *CompilerGLSL::format_to_glsl(spv::ImageFormat format)
{ {
auto check_desktop = [this] { auto check_desktop = [this] {
if (options.es) if (options.es)
throw CompilerError("Attempting to use image format not supported in ES profile."); SPIRV_CROSS_THROW("Attempting to use image format not supported in ES profile.");
}; };
switch (format) switch (format)
@ -747,7 +747,7 @@ uint32_t CompilerGLSL::type_to_std430_alignment(const SPIRType &type, uint64_t f
// Rule 8 implied. // Rule 8 implied.
} }
throw CompilerError("Did not find suitable std430 rule for type. Bogus decorations?"); SPIRV_CROSS_THROW("Did not find suitable std430 rule for type. Bogus decorations?");
} }
uint32_t CompilerGLSL::type_to_std430_array_stride(const SPIRType &type, uint64_t flags) uint32_t CompilerGLSL::type_to_std430_array_stride(const SPIRType &type, uint64_t flags)
@ -978,7 +978,7 @@ void CompilerGLSL::emit_push_constant_block_glsl(const SPIRVariable &var)
#if 0 #if 0
if (flags & ((1ull << DecorationBinding) | (1ull << DecorationDescriptorSet))) if (flags & ((1ull << DecorationBinding) | (1ull << DecorationDescriptorSet)))
throw CompilerError("Push constant blocks cannot be compiled to GLSL with Binding or Set syntax. " SPIRV_CROSS_THROW("Push constant blocks cannot be compiled to GLSL with Binding or Set syntax. "
"Remap to location with reflection API first or disable these decorations."); "Remap to location with reflection API first or disable these decorations.");
#endif #endif
@ -1096,7 +1096,7 @@ void CompilerGLSL::emit_uniform(const SPIRVariable &var)
if (!options.es && options.version < 420) if (!options.es && options.version < 420)
require_extension("GL_ARB_shader_image_load_store"); require_extension("GL_ARB_shader_image_load_store");
else if (options.es && options.version < 310) else if (options.es && options.version < 310)
throw CompilerError("At least ESSL 3.10 required for shader image load store."); SPIRV_CROSS_THROW("At least ESSL 3.10 required for shader image load store.");
} }
add_resource_name(var.self); add_resource_name(var.self);
@ -1182,14 +1182,14 @@ void CompilerGLSL::replace_fragment_output(SPIRVariable &var)
// FIXME: This seems like an extremely odd-ball case, so it's probably fine to leave it like this for now. // FIXME: This seems like an extremely odd-ball case, so it's probably fine to leave it like this for now.
m.alias = "gl_FragData"; m.alias = "gl_FragData";
if (location != 0) if (location != 0)
throw CompilerError("Arrayed output variable used, but location is not 0. " SPIRV_CROSS_THROW("Arrayed output variable used, but location is not 0. "
"This is unimplemented in SPIRV-Cross."); "This is unimplemented in SPIRV-Cross.");
if (is_legacy_es()) if (is_legacy_es())
require_extension("GL_EXT_draw_buffers"); require_extension("GL_EXT_draw_buffers");
} }
else else
throw CompilerError("Array-of-array output variable used. This cannot be implemented in legacy GLSL."); SPIRV_CROSS_THROW("Array-of-array output variable used. This cannot be implemented in legacy GLSL.");
var.compat_builtin = true; // We don't want to declare this variable, but use the name as-is. var.compat_builtin = true; // We don't want to declare this variable, but use the name as-is.
} }
@ -1234,13 +1234,13 @@ void CompilerGLSL::emit_pls()
{ {
auto &execution = get_entry_point(); auto &execution = get_entry_point();
if (execution.model != ExecutionModelFragment) if (execution.model != ExecutionModelFragment)
throw CompilerError("Pixel local storage only supported in fragment shaders."); SPIRV_CROSS_THROW("Pixel local storage only supported in fragment shaders.");
if (!options.es) if (!options.es)
throw CompilerError("Pixel local storage only supported in OpenGL ES."); SPIRV_CROSS_THROW("Pixel local storage only supported in OpenGL ES.");
if (options.version < 300) if (options.version < 300)
throw CompilerError("Pixel local storage only supported in ESSL 3.0 and above."); SPIRV_CROSS_THROW("Pixel local storage only supported in ESSL 3.0 and above.");
if (!pls_inputs.empty()) if (!pls_inputs.empty())
{ {
@ -1651,7 +1651,7 @@ string CompilerGLSL::constant_op_expression(const SPIRConstantOp &cop)
case OpSelect: case OpSelect:
{ {
if (cop.arguments.size() < 3) if (cop.arguments.size() < 3)
throw CompilerError("Not enough arguments to OpSpecConstantOp."); SPIRV_CROSS_THROW("Not enough arguments to OpSpecConstantOp.");
// This one is pretty annoying. It's triggered from // This one is pretty annoying. It's triggered from
// uint(bool), int(bool) from spec constants. // uint(bool), int(bool) from spec constants.
@ -1660,7 +1660,7 @@ string CompilerGLSL::constant_op_expression(const SPIRConstantOp &cop)
// If we cannot, fail. // If we cannot, fail.
if (!to_trivial_mix_op(type, op, cop.arguments[2], cop.arguments[1], cop.arguments[0])) if (!to_trivial_mix_op(type, op, cop.arguments[2], cop.arguments[1], cop.arguments[0]))
{ {
throw CompilerError( SPIRV_CROSS_THROW(
"Cannot implement specialization constant op OpSelect. " "Cannot implement specialization constant op OpSelect. "
"Need trivial select implementation which can be resolved to a simple cast from boolean."); "Need trivial select implementation which can be resolved to a simple cast from boolean.");
} }
@ -1669,7 +1669,7 @@ string CompilerGLSL::constant_op_expression(const SPIRConstantOp &cop)
default: default:
// Some opcodes are unimplemented here, these are currently not possible to test from glslang. // Some opcodes are unimplemented here, these are currently not possible to test from glslang.
throw CompilerError("Unimplemented spec constant op."); SPIRV_CROSS_THROW("Unimplemented spec constant op.");
} }
SPIRType::BaseType input_type; SPIRType::BaseType input_type;
@ -1692,7 +1692,7 @@ string CompilerGLSL::constant_op_expression(const SPIRConstantOp &cop)
if (binary) if (binary)
{ {
if (cop.arguments.size() < 2) if (cop.arguments.size() < 2)
throw CompilerError("Not enough arguments to OpSpecConstantOp."); SPIRV_CROSS_THROW("Not enough arguments to OpSpecConstantOp.");
string cast_op0; string cast_op0;
string cast_op1; string cast_op1;
@ -1714,7 +1714,7 @@ string CompilerGLSL::constant_op_expression(const SPIRConstantOp &cop)
else if (unary) else if (unary)
{ {
if (cop.arguments.size() < 1) if (cop.arguments.size() < 1)
throw CompilerError("Not enough arguments to OpSpecConstantOp."); SPIRV_CROSS_THROW("Not enough arguments to OpSpecConstantOp.");
// Auto-bitcast to result type as needed. // Auto-bitcast to result type as needed.
// Works around various casting scenarios in glslang as there is no OpBitcast for specialization constants. // Works around various casting scenarios in glslang as there is no OpBitcast for specialization constants.
@ -1723,7 +1723,7 @@ string CompilerGLSL::constant_op_expression(const SPIRConstantOp &cop)
else else
{ {
if (cop.arguments.size() < 1) if (cop.arguments.size() < 1)
throw CompilerError("Not enough arguments to OpSpecConstantOp."); SPIRV_CROSS_THROW("Not enough arguments to OpSpecConstantOp.");
return join(op, "(", to_expression(cop.arguments[0]), ")"); return join(op, "(", to_expression(cop.arguments[0]), ")");
} }
} }
@ -1939,7 +1939,7 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t
break; break;
default: default:
throw CompilerError("Invalid constant expression basetype."); SPIRV_CROSS_THROW("Invalid constant expression basetype.");
} }
if (c.vector_size() > 1) if (c.vector_size() > 1)
@ -2206,7 +2206,9 @@ string CompilerGLSL::legacy_tex_op(const std::string &op, const SPIRType &imgtyp
else if (op == "textureProjLod") else if (op == "textureProjLod")
return join("texture", type, is_legacy_es() ? "ProjLodEXT" : "ProjLod"); return join("texture", type, is_legacy_es() ? "ProjLodEXT" : "ProjLod");
else else
throw CompilerError(join("Unsupported legacy texture op: ", op)); {
SPIRV_CROSS_THROW(join("Unsupported legacy texture op: ", op));
}
} }
bool CompilerGLSL::to_trivial_mix_op(const SPIRType &type, string &op, uint32_t left, uint32_t right, uint32_t lerp) bool CompilerGLSL::to_trivial_mix_op(const SPIRType &type, string &op, uint32_t left, uint32_t right, uint32_t lerp)
@ -2351,7 +2353,7 @@ string CompilerGLSL::to_combined_image_sampler(uint32_t image_id, uint32_t samp_
return to_expression(itr->id); return to_expression(itr->id);
else else
{ {
throw CompilerError( SPIRV_CROSS_THROW(
"Cannot find mapping for combined sampler parameter, was build_combined_image_samplers() used " "Cannot find mapping for combined sampler parameter, was build_combined_image_samplers() used "
"before compile() was called?"); "before compile() was called?");
} }
@ -2368,8 +2370,8 @@ string CompilerGLSL::to_combined_image_sampler(uint32_t image_id, uint32_t samp_
return to_expression(itr->combined_id); return to_expression(itr->combined_id);
else else
{ {
throw CompilerError("Cannot find mapping for combined sampler, was build_combined_image_samplers() used " SPIRV_CROSS_THROW("Cannot find mapping for combined sampler, was build_combined_image_samplers() used "
"before compile() was called?"); "before compile() was called?");
} }
} }
} }
@ -2392,7 +2394,7 @@ void CompilerGLSL::emit_texture_op(const Instruction &i)
uint32_t length = i.length; uint32_t length = i.length;
if (i.offset + length > spirv.size()) if (i.offset + length > spirv.size())
throw CompilerError("Compiler::parse() opcode out of range."); SPIRV_CROSS_THROW("Compiler::parse() opcode out of range.");
uint32_t result_type = ops[0]; uint32_t result_type = ops[0];
uint32_t id = ops[1]; uint32_t id = ops[1];
@ -2671,7 +2673,7 @@ void CompilerGLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
if ((options.es && options.version >= 300) || (!options.es && options.version >= 130)) if ((options.es && options.version >= 300) || (!options.es && options.version >= 130))
emit_unary_func_op(result_type, id, args[0], "roundEven"); emit_unary_func_op(result_type, id, args[0], "roundEven");
else else
throw CompilerError("roundEven supported only in ESSL 300 and GLSL 130 and up."); SPIRV_CROSS_THROW("roundEven supported only in ESSL 300 and GLSL 130 and up.");
break; break;
case GLSLstd450Trunc: case GLSLstd450Trunc:
@ -2957,12 +2959,12 @@ string CompilerGLSL::builtin_to_glsl(BuiltIn builtin)
return "gl_PointSize"; return "gl_PointSize";
case BuiltInVertexId: case BuiltInVertexId:
if (options.vulkan_semantics) if (options.vulkan_semantics)
throw CompilerError( SPIRV_CROSS_THROW(
"Cannot implement gl_VertexID in Vulkan GLSL. This shader was created with GL semantics."); "Cannot implement gl_VertexID in Vulkan GLSL. This shader was created with GL semantics.");
return "gl_VertexID"; return "gl_VertexID";
case BuiltInInstanceId: case BuiltInInstanceId:
if (options.vulkan_semantics) if (options.vulkan_semantics)
throw CompilerError( SPIRV_CROSS_THROW(
"Cannot implement gl_InstanceID in Vulkan GLSL. This shader was created with GL semantics."); "Cannot implement gl_InstanceID in Vulkan GLSL. This shader was created with GL semantics.");
return "gl_InstanceID"; return "gl_InstanceID";
case BuiltInVertexIndex: case BuiltInVertexIndex:
@ -3025,7 +3027,7 @@ const char *CompilerGLSL::index_to_swizzle(uint32_t index)
case 3: case 3:
return "w"; return "w";
default: default:
throw CompilerError("Swizzle index out of range"); SPIRV_CROSS_THROW("Swizzle index out of range");
} }
} }
@ -3074,7 +3076,7 @@ string CompilerGLSL::access_chain(uint32_t base, const uint32_t *indices, uint32
index = get<SPIRConstant>(index).scalar(); index = get<SPIRConstant>(index).scalar();
if (index >= type->member_types.size()) if (index >= type->member_types.size())
throw CompilerError("Member index is out of bounds!"); SPIRV_CROSS_THROW("Member index is out of bounds!");
BuiltIn builtin; BuiltIn builtin;
if (is_member_builtin(*type, index, &builtin)) if (is_member_builtin(*type, index, &builtin))
@ -3148,7 +3150,7 @@ string CompilerGLSL::access_chain(uint32_t base, const uint32_t *indices, uint32
temp.vecsize = 1; temp.vecsize = 1;
} }
else else
throw CompilerError("Cannot subdivide a scalar value!"); SPIRV_CROSS_THROW("Cannot subdivide a scalar value!");
} }
return expr; return expr;
@ -3656,7 +3658,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
length -= 2; length -= 2;
if (!length) if (!length)
throw CompilerError("Invalid input to OpCompositeConstruct."); SPIRV_CROSS_THROW("Invalid input to OpCompositeConstruct.");
bool forward = true; bool forward = true;
for (uint32_t i = 0; i < length; i++) for (uint32_t i = 0; i < length; i++)
@ -4233,7 +4235,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
break; break;
} }
default: default:
throw CompilerError("Illegal argument to OpQuantizeToF16."); SPIRV_CROSS_THROW("Illegal argument to OpQuantizeToF16.");
} }
emit_op(result_type, id, op, should_forward(arg)); emit_op(result_type, id, op, should_forward(arg));
@ -4460,7 +4462,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
BFOP(textureQueryLOD); BFOP(textureQueryLOD);
} }
else if (options.es) else if (options.es)
throw CompilerError("textureQueryLod not supported in ES profile."); SPIRV_CROSS_THROW("textureQueryLod not supported in ES profile.");
else else
BFOP(textureQueryLod); BFOP(textureQueryLod);
break; break;
@ -4471,7 +4473,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
if (!options.es && options.version < 430) if (!options.es && options.version < 430)
require_extension("GL_ARB_texture_query_levels"); require_extension("GL_ARB_texture_query_levels");
if (options.es) if (options.es)
throw CompilerError("textureQueryLevels not supported in ES profile."); SPIRV_CROSS_THROW("textureQueryLevels not supported in ES profile.");
UFOP(textureQueryLevels); UFOP(textureQueryLevels);
break; break;
} }
@ -4480,7 +4482,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
{ {
auto *var = maybe_get_backing_variable(ops[2]); auto *var = maybe_get_backing_variable(ops[2]);
if (!var) if (!var)
throw CompilerError( SPIRV_CROSS_THROW(
"Bug. OpImageQuerySamples must have a backing variable so we know if the image is sampled or not."); "Bug. OpImageQuerySamples must have a backing variable so we know if the image is sampled or not.");
auto &type = get<SPIRType>(var->basetype); auto &type = get<SPIRType>(var->basetype);
@ -4531,7 +4533,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
if (var && var->remapped_variable) // Remapped input, just read as-is without any op-code if (var && var->remapped_variable) // Remapped input, just read as-is without any op-code
{ {
if (type.image.ms) if (type.image.ms)
throw CompilerError("Trying to remap multisampled image to variable, this is not possible."); SPIRV_CROSS_THROW("Trying to remap multisampled image to variable, this is not possible.");
auto itr = auto itr =
find_if(begin(pls_inputs), end(pls_inputs), [var](const PlsRemap &pls) { return pls.id == var->self; }); find_if(begin(pls_inputs), end(pls_inputs), [var](const PlsRemap &pls) { return pls.id == var->self; });
@ -4541,7 +4543,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
// For non-PLS inputs, we rely on subpass type remapping information to get it right // For non-PLS inputs, we rely on subpass type remapping information to get it right
// since ImageRead always returns 4-component vectors and the backing type is opaque. // since ImageRead always returns 4-component vectors and the backing type is opaque.
if (!var->remapped_components) if (!var->remapped_components)
throw CompilerError("subpassInput was remapped, but remap_components is not set correctly."); SPIRV_CROSS_THROW("subpassInput was remapped, but remap_components is not set correctly.");
imgexpr = remap_swizzle(result_type, var->remapped_components, ops[2]); imgexpr = remap_swizzle(result_type, var->remapped_components, ops[2]);
} }
else else
@ -4562,7 +4564,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
{ {
uint32_t operands = ops[4]; uint32_t operands = ops[4];
if (operands != ImageOperandsSampleMask || length != 6) if (operands != ImageOperandsSampleMask || length != 6)
throw CompilerError( SPIRV_CROSS_THROW(
"Multisampled image used in OpImageRead, but unexpected operand mask was used."); "Multisampled image used in OpImageRead, but unexpected operand mask was used.");
uint32_t samples = ops[5]; uint32_t samples = ops[5];
@ -4577,7 +4579,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
{ {
uint32_t operands = ops[4]; uint32_t operands = ops[4];
if (operands != ImageOperandsSampleMask || length != 6) if (operands != ImageOperandsSampleMask || length != 6)
throw CompilerError( SPIRV_CROSS_THROW(
"Multisampled image used in OpImageRead, but unexpected operand mask was used."); "Multisampled image used in OpImageRead, but unexpected operand mask was used.");
uint32_t samples = ops[5]; uint32_t samples = ops[5];
@ -4599,8 +4601,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
{ {
uint32_t operands = ops[4]; uint32_t operands = ops[4];
if (operands != ImageOperandsSampleMask || length != 6) if (operands != ImageOperandsSampleMask || length != 6)
throw CompilerError( SPIRV_CROSS_THROW("Multisampled image used in OpImageRead, but unexpected operand mask was used.");
"Multisampled image used in OpImageRead, but unexpected operand mask was used.");
uint32_t samples = ops[5]; uint32_t samples = ops[5];
imgexpr = join("imageLoad(", to_expression(ops[2]), ", ", to_expression(ops[3]), ", ", imgexpr = join("imageLoad(", to_expression(ops[2]), ", ", to_expression(ops[3]), ", ",
@ -4660,7 +4661,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
{ {
uint32_t operands = ops[3]; uint32_t operands = ops[3];
if (operands != ImageOperandsSampleMask || length != 5) if (operands != ImageOperandsSampleMask || length != 5)
throw CompilerError("Multisampled image used in OpImageWrite, but unexpected operand mask was used."); SPIRV_CROSS_THROW("Multisampled image used in OpImageWrite, but unexpected operand mask was used.");
uint32_t samples = ops[4]; uint32_t samples = ops[4];
statement("imageStore(", to_expression(ops[0]), ", ", to_expression(ops[1]), ", ", to_expression(samples), statement("imageStore(", to_expression(ops[0]), ", ", to_expression(ops[1]), ", ", to_expression(samples),
", ", to_expression(ops[2]), ");"); ", ", to_expression(ops[2]), ");");
@ -4686,7 +4687,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
emit_op(result_type, id, join("imageSize(", to_expression(ops[2]), ")"), true); emit_op(result_type, id, join("imageSize(", to_expression(ops[2]), ")"), true);
} }
else else
throw CompilerError("Invalid type for OpImageQuerySize."); SPIRV_CROSS_THROW("Invalid type for OpImageQuerySize.");
break; break;
} }
@ -4801,7 +4802,7 @@ bool CompilerGLSL::is_non_native_row_major_matrix(uint32_t id)
// swaps matrix elements while retaining the original dimensional form of the matrix. // swaps matrix elements while retaining the original dimensional form of the matrix.
const auto type = expression_type(id); const auto type = expression_type(id);
if (type.columns != type.vecsize) if (type.columns != type.vecsize)
throw CompilerError("Row-major matrices must be square on this platform."); SPIRV_CROSS_THROW("Row-major matrices must be square on this platform.");
return true; return true;
} }
@ -4822,7 +4823,7 @@ bool CompilerGLSL::member_is_non_native_row_major_matrix(const SPIRType &type, u
// swaps matrix elements while retaining the original dimensional form of the matrix. // swaps matrix elements while retaining the original dimensional form of the matrix.
const auto mbr_type = get<SPIRType>(type.member_types[index]); const auto mbr_type = get<SPIRType>(type.member_types[index]);
if (mbr_type.columns != mbr_type.vecsize) if (mbr_type.columns != mbr_type.vecsize)
throw CompilerError("Row-major matrices must be square on this platform."); SPIRV_CROSS_THROW("Row-major matrices must be square on this platform.");
return true; return true;
} }
@ -4989,7 +4990,7 @@ uint32_t CompilerGLSL::to_array_size_literal(const SPIRType &type, uint32_t inde
assert(type.array.size() == type.array_size_literal.size()); assert(type.array.size() == type.array_size_literal.size());
if (!type.array_size_literal[index]) if (!type.array_size_literal[index])
throw CompilerError("The array size is not a literal, but a specialization constant or spec constant op."); SPIRV_CROSS_THROW("The array size is not a literal, but a specialization constant or spec constant op.");
return type.array[index]; return type.array[index];
} }
@ -5086,7 +5087,7 @@ string CompilerGLSL::image_type_glsl(const SPIRType &type)
res += "2D"; res += "2D";
break; break;
default: default:
throw CompilerError("Only 1D, 2D, 3D, Buffer, InputTarget and Cube textures supported."); SPIRV_CROSS_THROW("Only 1D, 2D, 3D, Buffer, InputTarget and Cube textures supported.");
} }
if (type.image.ms) if (type.image.ms)
@ -5746,7 +5747,7 @@ bool CompilerGLSL::attempt_emit_loop_header(SPIRBlock &block, SPIRBlock::Method
break; break;
default: default:
throw CompilerError("For/while loop detected, but need while/for loop semantics."); SPIRV_CROSS_THROW("For/while loop detected, but need while/for loop semantics.");
} }
begin_scope(); begin_scope();
@ -5793,7 +5794,7 @@ bool CompilerGLSL::attempt_emit_loop_header(SPIRBlock &block, SPIRBlock::Method
break; break;
default: default:
throw CompilerError("For/while loop detected, but need while/for loop semantics."); SPIRV_CROSS_THROW("For/while loop detected, but need while/for loop semantics.");
} }
begin_scope(); begin_scope();
@ -5959,7 +5960,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
statement("default:"); statement("default:");
begin_scope(); begin_scope();
if (is_break(block.default_block)) if (is_break(block.default_block))
throw CompilerError("Cannot break; out of a switch statement and out of a loop at the same time ..."); SPIRV_CROSS_THROW("Cannot break; out of a switch statement and out of a loop at the same time ...");
branch(block.self, block.default_block); branch(block.self, block.default_block);
end_scope(); end_scope();
} }
@ -6000,7 +6001,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
break; break;
default: default:
throw CompilerError("Unimplemented block terminator."); SPIRV_CROSS_THROW("Unimplemented block terminator.");
} }
if (block.next_block && emit_next_block) if (block.next_block && emit_next_block)
@ -6046,7 +6047,7 @@ void CompilerGLSL::begin_scope()
void CompilerGLSL::end_scope() void CompilerGLSL::end_scope()
{ {
if (!indent) if (!indent)
throw CompilerError("Popping empty indent stack."); SPIRV_CROSS_THROW("Popping empty indent stack.");
indent--; indent--;
statement("}"); statement("}");
} }
@ -6054,7 +6055,7 @@ void CompilerGLSL::end_scope()
void CompilerGLSL::end_scope_decl() void CompilerGLSL::end_scope_decl()
{ {
if (!indent) if (!indent)
throw CompilerError("Popping empty indent stack."); SPIRV_CROSS_THROW("Popping empty indent stack.");
indent--; indent--;
statement("};"); statement("};");
} }
@ -6062,7 +6063,7 @@ void CompilerGLSL::end_scope_decl()
void CompilerGLSL::end_scope_decl(const string &decl) void CompilerGLSL::end_scope_decl(const string &decl)
{ {
if (!indent) if (!indent)
throw CompilerError("Popping empty indent stack."); SPIRV_CROSS_THROW("Popping empty indent stack.");
indent--; indent--;
statement("} ", decl, ";"); statement("} ", decl, ";");
} }
@ -6082,10 +6083,10 @@ void CompilerGLSL::check_function_call_constraints(const uint32_t *args, uint32_
auto &type = get<SPIRType>(var->basetype); auto &type = get<SPIRType>(var->basetype);
if (type.basetype == SPIRType::Image && type.image.dim == DimSubpassData) if (type.basetype == SPIRType::Image && type.image.dim == DimSubpassData)
{ {
throw CompilerError("Tried passing a remapped subpassInput variable to a function. " SPIRV_CROSS_THROW("Tried passing a remapped subpassInput variable to a function. "
"This will not work correctly because type-remapping information is lost. " "This will not work correctly because type-remapping information is lost. "
"To workaround, please consider not passing the subpass input as a function parameter, " "To workaround, please consider not passing the subpass input as a function parameter, "
"or use in/out variables instead which do not need type remapping information."); "or use in/out variables instead which do not need type remapping information.");
} }
} }
} }

Просмотреть файл

@ -70,7 +70,7 @@ string CompilerMSL::compile(MSLConfiguration &msl_cfg, vector<MSLVertexAttr> *p_
do do
{ {
if (pass_count >= 3) if (pass_count >= 3)
throw CompilerError("Over 3 compilation loops detected. Must be a bug!"); SPIRV_CROSS_THROW("Over 3 compilation loops detected. Must be a bug!");
reset(); reset();
@ -688,7 +688,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
} }
} }
else else
throw CompilerError("Invalid type for OpImageQuerySize."); SPIRV_CROSS_THROW("Invalid type for OpImageQuerySize.");
break; break;
} }
@ -819,7 +819,7 @@ void CompilerMSL::emit_texture_op(const Instruction &i)
uint32_t length = i.length; uint32_t length = i.length;
if (i.offset + length > spirv.size()) if (i.offset + length > spirv.size())
throw CompilerError("Compiler::compile() opcode out of range."); SPIRV_CROSS_THROW("Compiler::compile() opcode out of range.");
uint32_t result_type = ops[0]; uint32_t result_type = ops[0];
uint32_t id = ops[1]; uint32_t id = ops[1];
@ -1938,7 +1938,7 @@ size_t CompilerMSL::get_declared_type_size(const SPIRType &type, uint64_t dec_ma
case SPIRType::Image: case SPIRType::Image:
case SPIRType::SampledImage: case SPIRType::SampledImage:
case SPIRType::Sampler: case SPIRType::Sampler:
throw CompilerError("Querying size of object with opaque size."); SPIRV_CROSS_THROW("Querying size of object with opaque size.");
default: default:
break; break;
} }
@ -1972,7 +1972,7 @@ size_t CompilerMSL::get_declared_type_size(const SPIRType &type, uint64_t dec_ma
return dec.array_stride * to_array_size_literal(type, uint32_t(type.array.size()) - 1); return dec.array_stride * to_array_size_literal(type, uint32_t(type.array.size()) - 1);
else else
{ {
throw CompilerError("Type does not have ArrayStride set."); SPIRV_CROSS_THROW("Type does not have ArrayStride set.");
} }
} }
} }