Merge pull request #85 from godlikepanos/master
Add the option to build without exceptions
This commit is contained in:
Коммит
9ccd1aea42
|
@ -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()
|
||||||
|
|
6
Makefile
6
Makefile
|
@ -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.
|
||||||
|
|
25
main.cpp
25
main.cpp
|
@ -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;
|
||||||
|
|
125
spirv_glsl.cpp
125
spirv_glsl.cpp
|
@ -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.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче