Compare commits
20 Commits
docs-updat
...
exv/glslko
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0709f7d59a | ||
|
|
2027c9e237 | ||
|
|
86456c9e34 | ||
|
|
fad58ba892 | ||
|
|
8ae296974c | ||
|
|
f9575675d9 | ||
|
|
71025cf25a | ||
|
|
a067fb02b1 | ||
|
|
ffde51ee6f | ||
|
|
35f99ed168 | ||
|
|
a939ad03f8 | ||
|
|
05e628fff9 | ||
|
|
ad8473760a | ||
|
|
cb672eb063 | ||
|
|
9811b785cb | ||
|
|
ff6d4d721e | ||
|
|
c8a5094c41 | ||
|
|
0f34603cfc | ||
|
|
300f80448d | ||
|
|
a41d343a75 |
@@ -1,7 +1,8 @@
|
||||
;;; Directory Local Variables -*- no-byte-compile: t -*-
|
||||
;;; For more information see (info "(emacs) Directory Variables")
|
||||
|
||||
((c++-mode . ((c-file-style . "filament")
|
||||
((c++-mode . ((eglot-ignored-server-capabilities . (:documentFormattingProvider))
|
||||
(c-file-style . "filament")
|
||||
(apheleia-inhibit . t)))
|
||||
(c-mode . ((c-file-style . "filament")
|
||||
(apheleia-inhibit . t))))
|
||||
|
||||
@@ -757,6 +757,7 @@ if (FILAMENT_BUILD_FILAMAT OR IS_HOST_PLATFORM)
|
||||
add_subdirectory(${EXTERNAL}/spirv-tools)
|
||||
add_subdirectory(${EXTERNAL}/glslang/tnt)
|
||||
add_subdirectory(${EXTERNAL}/spirv-cross/tnt)
|
||||
add_subdirectory(${LIBRARIES}/astrict)
|
||||
add_subdirectory(${LIBRARIES}/filamat)
|
||||
|
||||
# the material debugger requires filamat
|
||||
|
||||
108
libs/astrict/CMakeLists.txt
Normal file
108
libs/astrict/CMakeLists.txt
Normal file
@@ -0,0 +1,108 @@
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
project(astrict)
|
||||
|
||||
set(TARGET astrict)
|
||||
set(PUBLIC_HDR_DIR include)
|
||||
|
||||
# ==================================================================================================
|
||||
# Sources and headers
|
||||
# ==================================================================================================
|
||||
set(HDRS
|
||||
include/astrict/CommonTypes.h
|
||||
include/astrict/DebugCommon.h
|
||||
include/astrict/DebugGlsl.h
|
||||
include/astrict/FromGlsl.h
|
||||
include/astrict/GlslTypes.h
|
||||
include/astrict/ToGlsl.h)
|
||||
|
||||
set(PRIVATE_HDRS)
|
||||
|
||||
set(SRCS
|
||||
src/DebugCommon.cpp
|
||||
src/DebugGlsl.cpp
|
||||
src/FromGlsl.cpp
|
||||
src/ToGlsl.cpp)
|
||||
|
||||
# ==================================================================================================
|
||||
# Include and target definitions
|
||||
# ==================================================================================================
|
||||
include_directories(${PUBLIC_HDR_DIR})
|
||||
include_directories(${CMAKE_BINARY_DIR})
|
||||
|
||||
# astrict
|
||||
add_library(${TARGET} STATIC ${HDRS} ${PRIVATE_HDRS} ${SRCS})
|
||||
target_include_directories(${TARGET} PUBLIC ${PUBLIC_HDR_DIR})
|
||||
set_target_properties(${TARGET} PROPERTIES FOLDER Libs)
|
||||
target_link_libraries(${TARGET} backend_headers math utils)
|
||||
|
||||
# We are being naughty and accessing private headers here
|
||||
# For spirv-tools, we're just following glslang's example
|
||||
target_include_directories(${TARGET} PRIVATE ${spirv-tools_SOURCE_DIR}/include)
|
||||
|
||||
# glslang libraries have circular dependencies. To make sure the proper object are part of the link
|
||||
# we need to force archive re-scan on new symbol dependencies via start/end-group.
|
||||
# Read more about this here https://eli.thegreenplace.net/2013/07/09/library-order-in-static-linking
|
||||
if (APPLE OR MSVC)
|
||||
target_link_libraries(${TARGET} glslang SPIRV SPIRV-Tools-opt spirv-cross-glsl)
|
||||
else()
|
||||
target_link_libraries(${TARGET}
|
||||
-Wl,--start-group glslang SPIRV SPIRV-Tools-opt spirv-cross-glsl -Wl,--end-group)
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
# Compiler flags
|
||||
# ==================================================================================================
|
||||
# this must match options enabled in glslang's CMakeLists.txt
|
||||
target_compile_options(${TARGET} PRIVATE -DAMD_EXTENSIONS -DNV_EXTENSIONS )
|
||||
|
||||
if (MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W0 /Zc:__cplusplus")
|
||||
endif()
|
||||
|
||||
if (FILAMENT_ENABLE_MATDBG)
|
||||
add_definitions(-DFILAMENT_ENABLE_MATDBG)
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
# Installation
|
||||
# ==================================================================================================
|
||||
|
||||
# Astrict has dependencies on a bunch of SPIRV-related libraries. To make things simpler, we bundle
|
||||
# them together into a single shared library and copy this into the installation folder. This
|
||||
# requires us to explicitly list the dependencies below, as CMake doesn't have a way to recursively
|
||||
# query dependencies.
|
||||
set(ASTRICT_DEPS
|
||||
OGLCompiler
|
||||
OSDependent
|
||||
SPIRV
|
||||
SPIRV-Tools
|
||||
SPIRV-Tools-opt
|
||||
astrict
|
||||
glslang
|
||||
spirv-cross-core
|
||||
spirv-cross-glsl
|
||||
spirv-cross-msl
|
||||
)
|
||||
|
||||
set(ASTRICT_COMBINED_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libastrict_combined.a")
|
||||
combine_static_libs(astrict "${ASTRICT_COMBINED_OUTPUT}" "${ASTRICT_DEPS}")
|
||||
|
||||
set(ASTRICT_LIB_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}astrict${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
install(FILES "${ASTRICT_COMBINED_OUTPUT}" DESTINATION lib/${DIST_DIR} RENAME ${ASTRICT_LIB_NAME})
|
||||
install(DIRECTORY ${PUBLIC_HDR_DIR}/astrict DESTINATION include)
|
||||
|
||||
# ==================================================================================================
|
||||
# Tests
|
||||
# ==================================================================================================
|
||||
project(test_astrict)
|
||||
set(TARGET test_astrict)
|
||||
set(SRCS
|
||||
tests/test_FromGlsl.cpp)
|
||||
|
||||
add_executable(${TARGET} ${SRCS})
|
||||
|
||||
target_include_directories(${TARGET} PRIVATE src)
|
||||
|
||||
target_link_libraries(${TARGET} astrict gtest)
|
||||
|
||||
set_target_properties(${TARGET} PROPERTIES FOLDER Tests)
|
||||
86
libs/astrict/include/astrict/AstrictBuilder.h
Normal file
86
libs/astrict/include/astrict/AstrictBuilder.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_ASTRICT_ASTRICT_BUILDER_H
|
||||
#define TNT_ASTRICT_ASTRICT_BUILDER_H
|
||||
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <astrict/CommonTypes.h>
|
||||
|
||||
namespace astrict {
|
||||
|
||||
using StringId = Newtype<int, struct StringIdTag>;
|
||||
using ExpressionId = Newtype<int, struct ExpressionIdTag>;
|
||||
using GlobalVariableId = Newtype<int, struct GlobalVariableIdTag>;
|
||||
using StructId = Newtype<int, struct StructIdTag>;
|
||||
using FunctionId = Newtype<int, struct FunctionIdTag>;
|
||||
|
||||
using LocalVariableId = Newtype<int, struct LocalVariableIdTag>;
|
||||
|
||||
template<typename Id, typename Value>
|
||||
class IdStore {
|
||||
public:
|
||||
// Inserts if non-existent.
|
||||
Id insert(Value value, bool* outWasExtant = nullptr) {
|
||||
auto it = mMap.find(value);
|
||||
if (it == mMap.end()) {
|
||||
Id id(mMap.size() + 1);
|
||||
mMap[value] = id;
|
||||
if (outWasExtant) {
|
||||
*outWasExtant = false;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
if (outWasExtant) {
|
||||
*outWasExtant = true;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
std::vector<Value> getFinal() {
|
||||
std::vector<Value> r(mMap.size());
|
||||
for (const auto& pair : mMap) {
|
||||
r[pair.second] = pair.first;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<Value, Id> mMap;
|
||||
};
|
||||
|
||||
using ByteVector = std::vector<uint8_t>;
|
||||
|
||||
class AstrictBuilder {
|
||||
public:
|
||||
std::vector<ByteVector> build();
|
||||
|
||||
private:
|
||||
IdStore<StringId, std::string> mStrings;
|
||||
IdStore<ExpressionId, ByteVector> mExpressions;
|
||||
IdStore<StructId, ByteVector> mStructs;
|
||||
IdStore<GlobalVariableId, ByteVector> mGlobalSymbols;
|
||||
IdStore<FunctionId, ByteVector> mFunctions;
|
||||
IdStore<FunctionId, ByteVector> mFunctionBodies;
|
||||
std::unordered_map<StructId, std::string> mStructNames;
|
||||
std::unordered_map<GlobalVariableId, std::string> mGlobalVariableNames;
|
||||
};
|
||||
|
||||
} // namespace astrict
|
||||
|
||||
#endif // TNT_ASTRICT_ASTRICT_BUILDER_H
|
||||
473
libs/astrict/include/astrict/CommonTypes.h
Normal file
473
libs/astrict/include/astrict/CommonTypes.h
Normal file
@@ -0,0 +1,473 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_ASTRICT_COMMONTYPES_H
|
||||
#define TNT_ASTRICT_COMMONTYPES_H
|
||||
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace astrict {
|
||||
|
||||
template<typename T, typename Tag>
|
||||
class Newtype {
|
||||
public:
|
||||
Newtype() : mValue() {}
|
||||
Newtype(const Newtype<T, Tag> &other) : mValue(other.mValue) {}
|
||||
Newtype(Newtype<T, Tag> &&other) : mValue(other.mValue) {}
|
||||
explicit Newtype(T& value) : mValue(value) {}
|
||||
explicit Newtype(T&& value) : mValue(value) {}
|
||||
|
||||
Newtype& operator=(const Newtype<T, Tag>& other) {
|
||||
mValue = other.mValue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Newtype& operator=(Newtype<T, Tag>&& other) {
|
||||
mValue = other.mValue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const T& operator*() const {
|
||||
return mValue;
|
||||
}
|
||||
|
||||
bool operator==(const Newtype<T, Tag>& o) const {
|
||||
return mValue == o.mValue;
|
||||
}
|
||||
|
||||
bool operator<(const Newtype<T, Tag>& o) const {
|
||||
return mValue < o.mValue;
|
||||
}
|
||||
private:
|
||||
T mValue;
|
||||
};
|
||||
|
||||
template<class>
|
||||
inline constexpr bool always_false_v = false;
|
||||
|
||||
} // namespace astrict
|
||||
|
||||
namespace std {
|
||||
|
||||
template<typename Tag>
|
||||
struct hash<astrict::Newtype<int, Tag>> {
|
||||
std::size_t operator()(const astrict::Newtype<int, Tag>& o) const {
|
||||
return *o;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Tag>
|
||||
struct hash<astrict::Newtype<uint16_t, Tag>> {
|
||||
std::size_t operator()(const astrict::Newtype<uint16_t, Tag>& o) const {
|
||||
return *o;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
namespace astrict {
|
||||
|
||||
enum class BranchOperator : uint8_t {
|
||||
Discard, // Fragment only
|
||||
TerminateInvocation, // Fragment only
|
||||
Demote, // Fragment only
|
||||
TerminateRayEXT, // Any-hit only
|
||||
IgnoreIntersectionEXT, // Any-hit only
|
||||
Return,
|
||||
Break,
|
||||
Continue,
|
||||
Case,
|
||||
Default,
|
||||
};
|
||||
|
||||
// Represents an operation whose syntax differs from a function call. For example, addition,
|
||||
// equality.
|
||||
enum class ExpressionOperator : uint8_t {
|
||||
// Unary
|
||||
Negative,
|
||||
LogicalNot,
|
||||
BitwiseNot,
|
||||
PostIncrement,
|
||||
PostDecrement,
|
||||
PreIncrement,
|
||||
PreDecrement,
|
||||
ArrayLength,
|
||||
|
||||
// Binary
|
||||
Add,
|
||||
Sub,
|
||||
Mul,
|
||||
Div,
|
||||
Mod,
|
||||
RightShift,
|
||||
LeftShift,
|
||||
And,
|
||||
InclusiveOr,
|
||||
ExclusiveOr,
|
||||
Equal,
|
||||
NotEqual,
|
||||
LessThan,
|
||||
GreaterThan,
|
||||
LessThanEqual,
|
||||
GreaterThanEqual,
|
||||
LogicalOr,
|
||||
LogicalXor,
|
||||
LogicalAnd,
|
||||
Index,
|
||||
Assign,
|
||||
AddAssign,
|
||||
SubAssign,
|
||||
MulAssign,
|
||||
DivAssign,
|
||||
ModAssign,
|
||||
AndAssign,
|
||||
InclusiveOrAssign,
|
||||
ExclusiveOrAssign,
|
||||
LeftShiftAssign,
|
||||
RightShiftAssign,
|
||||
|
||||
// Ternary
|
||||
Ternary,
|
||||
|
||||
// Variadic
|
||||
Comma,
|
||||
};
|
||||
|
||||
using VariableOrExpressionId = std::variant<GlobalVariableId, LocalVariableId, ExpressionId>;
|
||||
|
||||
struct StructMember {
|
||||
StringId qualifier;
|
||||
StringId type;
|
||||
|
||||
bool operator==(const StructMember& o) const {
|
||||
return qualifier == o.qualifier
|
||||
&& type == o.type;
|
||||
}
|
||||
};
|
||||
|
||||
struct Struct {
|
||||
StringId qualifier;
|
||||
std::vector<StructMember> members;
|
||||
std::vector<StringId> memberNames;
|
||||
|
||||
bool operator==(const Struct& o) const {
|
||||
return qualifier == o.qualifier
|
||||
&& members == o.members
|
||||
&& memberNames == o.memberNames;
|
||||
}
|
||||
};
|
||||
|
||||
struct Type {
|
||||
std::variant<StringId, StructId> name;
|
||||
std::optional<StringId> qualifiers;
|
||||
std::vector<std::size_t> arraySizes;
|
||||
|
||||
bool operator==(const Type& o) const {
|
||||
return name == o.name
|
||||
&& qualifiers == o.qualifiers
|
||||
&& arraySizes == o.arraySizes;
|
||||
}
|
||||
};
|
||||
|
||||
struct Variable {
|
||||
StringId qualifier;
|
||||
StringId type;
|
||||
std::optional<StringId> name;
|
||||
|
||||
bool operator==(const Variable& o) const {
|
||||
return qualifier == o.qualifier
|
||||
&& type == o.type
|
||||
&& name == o.name;
|
||||
}
|
||||
};
|
||||
|
||||
struct ExpressionOperandExpression {
|
||||
std::variant<ExpressionOperator, FunctionId, StructId> op;
|
||||
std::vector<VariableOrExpressionId> args;
|
||||
|
||||
bool operator==(const ExpressionOperandExpression& o) const {
|
||||
return op == o.op
|
||||
&& args == o.args;
|
||||
}
|
||||
};
|
||||
|
||||
struct VectorSwizzleExpression {
|
||||
VariableOrExpressionId operand;
|
||||
uint16_t swizzle;
|
||||
|
||||
bool operator==(const VectorSwizzleExpression& o) const {
|
||||
return operand == o.operand
|
||||
&& swizzle == o.swizzle;
|
||||
}
|
||||
};
|
||||
|
||||
struct IndexStructExpression {
|
||||
VariableOrExpressionId operand;
|
||||
StructId strukt;
|
||||
uint16_t index;
|
||||
|
||||
bool operator==(const IndexStructExpression& o) const {
|
||||
return operand == o.operand
|
||||
&& strukt == o.strukt
|
||||
&& index == o.index;
|
||||
}
|
||||
};
|
||||
|
||||
struct LiteralExpression {
|
||||
std::variant<
|
||||
bool,
|
||||
int,
|
||||
double,
|
||||
unsigned int> value;
|
||||
|
||||
bool operator==(const LiteralExpression& o) const {
|
||||
return value == o.value;
|
||||
}
|
||||
};
|
||||
|
||||
using Expression = std::variant<
|
||||
ExpressionOperandExpression,
|
||||
VectorSwizzleExpression,
|
||||
IndexStructExpression,
|
||||
LiteralExpression>;
|
||||
|
||||
struct Function {
|
||||
FunctionId name;
|
||||
TypeId returnType;
|
||||
std::vector<LocalVariableId> parameters;
|
||||
StatementBlockId body;
|
||||
std::unordered_map<LocalVariableId, Variable> localVariables;
|
||||
|
||||
bool operator==(const Function& o) const {
|
||||
return name == o.name
|
||||
&& returnType == o.returnType
|
||||
&& parameters == o.parameters
|
||||
&& body == o.body
|
||||
&& localVariables == o.localVariables;
|
||||
}
|
||||
};
|
||||
|
||||
struct IfStatement {
|
||||
VariableOrExpressionId condition;
|
||||
StatementBlockId thenBlock;
|
||||
std::optional<StatementBlockId> elseBlock;
|
||||
|
||||
bool operator==(const IfStatement& o) const {
|
||||
return condition == o.condition
|
||||
&& thenBlock == o.thenBlock
|
||||
&& elseBlock == o.elseBlock;
|
||||
}
|
||||
};
|
||||
|
||||
struct SwitchStatement {
|
||||
VariableOrExpressionId condition;
|
||||
StatementBlockId body;
|
||||
|
||||
bool operator==(const SwitchStatement& o) const {
|
||||
return condition == o.condition
|
||||
&& body == o.body;
|
||||
}
|
||||
};
|
||||
|
||||
struct BranchStatement {
|
||||
BranchOperator op;
|
||||
std::optional<VariableOrExpressionId> operand;
|
||||
|
||||
bool operator==(const BranchStatement& o) const {
|
||||
return op == o.op
|
||||
&& operand == o.operand;
|
||||
}
|
||||
};
|
||||
|
||||
struct LoopStatement {
|
||||
VariableOrExpressionId condition;
|
||||
std::optional<ExpressionId> terminal;
|
||||
bool testFirst;
|
||||
StatementBlockId body;
|
||||
|
||||
bool operator==(const LoopStatement& o) const {
|
||||
return condition == o.condition
|
||||
&& terminal == o.terminal
|
||||
&& testFirst == o.testFirst
|
||||
&& body == o.body;
|
||||
}
|
||||
};
|
||||
|
||||
using Statement = std::variant<
|
||||
ExpressionId,
|
||||
IfStatement,
|
||||
SwitchStatement,
|
||||
BranchStatement,
|
||||
LoopStatement>;
|
||||
|
||||
template <typename T, typename... Rest>
|
||||
void hashCombine(std::size_t& seed, const T& v, const Rest&... rest) {
|
||||
seed ^= std::hash<T>{}(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
(hashCombine(seed, rest), ...);
|
||||
}
|
||||
|
||||
} // namespace astrict
|
||||
|
||||
namespace std {
|
||||
|
||||
template<>
|
||||
struct hash<astrict::StructMember> {
|
||||
std::size_t operator()(const astrict::StructMember& o) const {
|
||||
std::size_t result = 0;
|
||||
astrict::hashCombine(result, o.name, o.type);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<astrict::Struct> {
|
||||
std::size_t operator()(const astrict::Struct& o) const {
|
||||
std::size_t result = 0;
|
||||
astrict::hashCombine(result, o.name, o.members.size());
|
||||
for (const auto& member : o.members) {
|
||||
astrict::hashCombine(result, member);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<astrict::Type> {
|
||||
std::size_t operator()(const astrict::Type& o) const {
|
||||
std::size_t result = 0;
|
||||
astrict::hashCombine(result, o.name, o.qualifiers, o.arraySizes.size());
|
||||
for (const auto& size : o.arraySizes) {
|
||||
astrict::hashCombine(result, size);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<astrict::Variable> {
|
||||
std::size_t operator()(const astrict::Variable& o) const {
|
||||
std::size_t result = 0;
|
||||
astrict::hashCombine(result, o.name, o.type);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<astrict::ExpressionOperandExpression> {
|
||||
std::size_t operator()(const astrict::ExpressionOperandExpression& o) const {
|
||||
std::size_t result = 0;
|
||||
astrict::hashCombine(result, o.op, o.args.size());
|
||||
for (const auto& arg : o.args) {
|
||||
astrict::hashCombine(result, arg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<astrict::IndexStructExpression> {
|
||||
std::size_t operator()(const astrict::IndexStructExpression& o) const {
|
||||
std::size_t result = 0;
|
||||
astrict::hashCombine(result, o.operand, o.strukt, o.index);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<astrict::VectorSwizzleExpression> {
|
||||
std::size_t operator()(const astrict::VectorSwizzleExpression& o) const {
|
||||
std::size_t result = 0;
|
||||
astrict::hashCombine(result, o.operand, o.swizzle);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<astrict::LiteralExpression> {
|
||||
std::size_t operator()(const astrict::LiteralExpression& o) const {
|
||||
std::size_t result = 0;
|
||||
astrict::hashCombine(result, o.value);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<astrict::Function> {
|
||||
std::size_t operator()(const astrict::Function& o) const {
|
||||
std::size_t result = 0;
|
||||
astrict::hashCombine(result, o.name, o.returnType, o.body,
|
||||
o.parameters.size(), o.localVariables.size());
|
||||
for (const auto& argument : o.parameters) {
|
||||
astrict::hashCombine(result, argument);
|
||||
}
|
||||
for (const auto& symbol : o.localVariables) {
|
||||
astrict::hashCombine(result, symbol.first, symbol.second);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<astrict::IfStatement> {
|
||||
std::size_t operator()(const astrict::IfStatement& o) const {
|
||||
std::size_t result = 0;
|
||||
astrict::hashCombine(result, o.condition, o.thenBlock, o.elseBlock);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<astrict::SwitchStatement> {
|
||||
std::size_t operator()(const astrict::SwitchStatement& o) const {
|
||||
std::size_t result = 0;
|
||||
astrict::hashCombine(result, o.condition, o.body);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<astrict::BranchStatement> {
|
||||
std::size_t operator()(const astrict::BranchStatement& o) const {
|
||||
std::size_t result = 0;
|
||||
astrict::hashCombine(result, o.op, o.operand);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<astrict::LoopStatement> {
|
||||
std::size_t operator()(const astrict::LoopStatement& o) const {
|
||||
std::size_t result = 0;
|
||||
astrict::hashCombine(result, o.condition, o.terminal, o.testFirst, o.body);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<std::vector<astrict::Statement>> {
|
||||
std::size_t operator()(const std::vector<astrict::Statement>& o) const {
|
||||
std::size_t result = o.size();
|
||||
for (const auto& statement : o) {
|
||||
astrict::hashCombine(result, statement);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // TNT_ASTRICT_COMMONTYPES_H
|
||||
28
libs/astrict/include/astrict/DebugCommon.h
Normal file
28
libs/astrict/include/astrict/DebugCommon.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_ASTRICT_DEBUGCOMMON_H
|
||||
#define TNT_ASTRICT_DEBUGCOMMON_H
|
||||
|
||||
#include <astrict/CommonTypes.h>
|
||||
|
||||
namespace astrict {
|
||||
|
||||
const char* rValueOperatorToString(ExpressionOperator op);
|
||||
|
||||
} // namespace astrict
|
||||
|
||||
#endif // TNT_ASTRICT_DEBUGCOMMON_H
|
||||
31
libs/astrict/include/astrict/DebugGlsl.h
Normal file
31
libs/astrict/include/astrict/DebugGlsl.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_ASTRICT_DEBUGGLSL_H
|
||||
#define TNT_ASTRICT_DEBUGGLSL_H
|
||||
|
||||
#include "glslang/Include/intermediate.h"
|
||||
|
||||
namespace astrict {
|
||||
|
||||
const char* glslangOperatorToString(glslang::TOperator op);
|
||||
std::string glslangNodeToString(const TIntermNode* node);
|
||||
std::string glslangLocToString(const glslang::TSourceLoc& loc);
|
||||
std::string glslangNodeToStringWithLoc(const TIntermNode* node);
|
||||
|
||||
} // namespace astrict
|
||||
|
||||
#endif // TNT_ASTRICT_DEBUGGLSL_H
|
||||
30
libs/astrict/include/astrict/FromGlsl.h
Normal file
30
libs/astrict/include/astrict/FromGlsl.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_ASTRICT_FROMGLSL_H
|
||||
#define TNT_ASTRICT_FROMGLSL_H
|
||||
|
||||
#include <astrict/GlslTypes.h>
|
||||
|
||||
#include "glslang/Include/intermediate.h"
|
||||
|
||||
namespace astrict {
|
||||
|
||||
PackFromGlsl fromGlsl(const glslang::TIntermediate& intermediate);
|
||||
|
||||
} // namespace astrict
|
||||
|
||||
#endif // TNT_ASTRICT_FROMGLSL_H
|
||||
46
libs/astrict/include/astrict/GlslTypes.h
Normal file
46
libs/astrict/include/astrict/GlslTypes.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_ASTRICT_GLSLTYPES_H
|
||||
#define TNT_ASTRICT_GLSLTYPES_H
|
||||
|
||||
#include <astrict/CommonTypes.h>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace astrict {
|
||||
|
||||
struct PackFromGlsl {
|
||||
int version;
|
||||
std::unordered_map<StringId, std::string> strings;
|
||||
std::unordered_map<TypeId, Type> types;
|
||||
std::unordered_map<StructId, Struct> structs;
|
||||
std::unordered_map<GlobalVariableId, Variable> globalVariables;
|
||||
std::unordered_map<ExpressionId, Expression> expressions;
|
||||
std::unordered_map<FunctionId, std::string> functionNames;
|
||||
std::unordered_map<StatementBlockId, std::vector<Statement>> statementBlocks;
|
||||
std::unordered_map<FunctionId, Function> functions;
|
||||
// The below serve as the roots for conversion to glsl.
|
||||
std::vector<StructId> structsInOrder;
|
||||
std::set<FunctionId> functionPrototypes;
|
||||
std::vector<std::pair<GlobalVariableId, VariableOrExpressionId>> globalSymbolsInOrder;
|
||||
std::vector<FunctionId> functionsInOrder;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif // TNT_ASTRICT_GLSLTYPES_H
|
||||
29
libs/astrict/include/astrict/ToGlsl.h
Normal file
29
libs/astrict/include/astrict/ToGlsl.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_ASTRICT_TOGLSL_H
|
||||
#define TNT_ASTRICT_TOGLSL_H
|
||||
|
||||
#include <astrict/GlslTypes.h>
|
||||
#include <sstream>
|
||||
|
||||
namespace astrict {
|
||||
|
||||
void toGlsl(const PackFromGlsl& pack, std::ostringstream& out);
|
||||
|
||||
};
|
||||
|
||||
#endif // TNT_ASTRICT_TOGLSL_H
|
||||
36
libs/astrict/src/AstrictBuilder.cpp
Normal file
36
libs/astrict/src/AstrictBuilder.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <astrict/AstrictBuilder.h>
|
||||
|
||||
#include <astrict/CommonTypes.h>
|
||||
#include <astrict/DebugGlsl.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
|
||||
#include "ConstantUnion.h"
|
||||
#include "Types.h"
|
||||
#include "glslang/MachineIndependent/localintermediate.h"
|
||||
#include "intermediate.h"
|
||||
#include "utils/ostream.h"
|
||||
|
||||
namespace astrict {
|
||||
|
||||
|
||||
|
||||
} // namespace astrict
|
||||
67
libs/astrict/src/DebugCommon.cpp
Normal file
67
libs/astrict/src/DebugCommon.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <astrict/DebugCommon.h>
|
||||
|
||||
namespace astrict {
|
||||
|
||||
const char* rValueOperatorToString(ExpressionOperator op) {
|
||||
switch(op) {
|
||||
case ExpressionOperator::Negative: return "Negative";
|
||||
case ExpressionOperator::LogicalNot: return "LogicalNot";
|
||||
case ExpressionOperator::BitwiseNot: return "BitwiseNot";
|
||||
case ExpressionOperator::PostIncrement: return "PostIncrement";
|
||||
case ExpressionOperator::PostDecrement: return "PostDecrement";
|
||||
case ExpressionOperator::PreIncrement: return "PreIncrement";
|
||||
case ExpressionOperator::PreDecrement: return "PreDecrement";
|
||||
case ExpressionOperator::ArrayLength: return "ArrayLength";
|
||||
case ExpressionOperator::Add: return "Add";
|
||||
case ExpressionOperator::Sub: return "Sub";
|
||||
case ExpressionOperator::Mul: return "Mul";
|
||||
case ExpressionOperator::Div: return "Div";
|
||||
case ExpressionOperator::Mod: return "Mod";
|
||||
case ExpressionOperator::RightShift: return "RightShift";
|
||||
case ExpressionOperator::LeftShift: return "LeftShift";
|
||||
case ExpressionOperator::And: return "And";
|
||||
case ExpressionOperator::InclusiveOr: return "InclusiveOr";
|
||||
case ExpressionOperator::ExclusiveOr: return "ExclusiveOr";
|
||||
case ExpressionOperator::Equal: return "Equal";
|
||||
case ExpressionOperator::NotEqual: return "NotEqual";
|
||||
case ExpressionOperator::LessThan: return "LessThan";
|
||||
case ExpressionOperator::GreaterThan: return "GreaterThan";
|
||||
case ExpressionOperator::LessThanEqual: return "LessThanEqual";
|
||||
case ExpressionOperator::GreaterThanEqual: return "GreaterThanEqual";
|
||||
case ExpressionOperator::LogicalOr: return "LogicalOr";
|
||||
case ExpressionOperator::LogicalXor: return "LogicalXor";
|
||||
case ExpressionOperator::LogicalAnd: return "LogicalAnd";
|
||||
case ExpressionOperator::Index: return "Index";
|
||||
case ExpressionOperator::Assign: return "Assign";
|
||||
case ExpressionOperator::AddAssign: return "AddAssign";
|
||||
case ExpressionOperator::SubAssign: return "SubAssign";
|
||||
case ExpressionOperator::MulAssign: return "MulAssign";
|
||||
case ExpressionOperator::DivAssign: return "DivAssign";
|
||||
case ExpressionOperator::ModAssign: return "ModAssign";
|
||||
case ExpressionOperator::AndAssign: return "AndAssign";
|
||||
case ExpressionOperator::InclusiveOrAssign: return "InclusiveOrAssign";
|
||||
case ExpressionOperator::ExclusiveOrAssign: return "ExclusiveOrAssign";
|
||||
case ExpressionOperator::LeftShiftAssign: return "LeftShiftAssign";
|
||||
case ExpressionOperator::RightShiftAssign: return "RightShiftAssign";
|
||||
case ExpressionOperator::Ternary: return "Ternary";
|
||||
case ExpressionOperator::Comma: return "Comma";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace astrict
|
||||
925
libs/astrict/src/DebugGlsl.cpp
Normal file
925
libs/astrict/src/DebugGlsl.cpp
Normal file
@@ -0,0 +1,925 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <astrict/DebugGlsl.h>
|
||||
|
||||
namespace astrict {
|
||||
|
||||
const char* glslangOperatorToString(glslang::TOperator op) {
|
||||
using namespace glslang;
|
||||
switch (op) {
|
||||
case EOpNull: return "EOpNull";
|
||||
case EOpSequence: return "EOpSequence";
|
||||
case EOpScope: return "EOpScope";
|
||||
case EOpLinkerObjects: return "EOpLinkerObjects";
|
||||
case EOpFunctionCall: return "EOpFunctionCall";
|
||||
case EOpFunction: return "EOpFunction";
|
||||
case EOpParameters: return "EOpParameters";
|
||||
case EOpSpirvInst: return "EOpSpirvInst";
|
||||
case EOpNegative: return "EOpNegative";
|
||||
case EOpLogicalNot: return "EOpLogicalNot";
|
||||
case EOpVectorLogicalNot: return "EOpVectorLogicalNot";
|
||||
case EOpBitwiseNot: return "EOpBitwiseNot";
|
||||
case EOpPostIncrement: return "EOpPostIncrement";
|
||||
case EOpPostDecrement: return "EOpPostDecrement";
|
||||
case EOpPreIncrement: return "EOpPreIncrement";
|
||||
case EOpPreDecrement: return "EOpPreDecrement";
|
||||
case EOpCopyObject: return "EOpCopyObject";
|
||||
case EOpDeclare: return "EOpDeclare";
|
||||
case EOpConvInt8ToBool: return "EOpConvInt8ToBool";
|
||||
case EOpConvUint8ToBool: return "EOpConvUint8ToBool";
|
||||
case EOpConvInt16ToBool: return "EOpConvInt16ToBool";
|
||||
case EOpConvUint16ToBool: return "EOpConvUint16ToBool";
|
||||
case EOpConvIntToBool: return "EOpConvIntToBool";
|
||||
case EOpConvUintToBool: return "EOpConvUintToBool";
|
||||
case EOpConvInt64ToBool: return "EOpConvInt64ToBool";
|
||||
case EOpConvUint64ToBool: return "EOpConvUint64ToBool";
|
||||
case EOpConvFloat16ToBool: return "EOpConvFloat16ToBool";
|
||||
case EOpConvFloatToBool: return "EOpConvFloatToBool";
|
||||
case EOpConvDoubleToBool: return "EOpConvDoubleToBool";
|
||||
case EOpConvBoolToInt8: return "EOpConvBoolToInt8";
|
||||
case EOpConvBoolToUint8: return "EOpConvBoolToUint8";
|
||||
case EOpConvBoolToInt16: return "EOpConvBoolToInt16";
|
||||
case EOpConvBoolToUint16: return "EOpConvBoolToUint16";
|
||||
case EOpConvBoolToInt: return "EOpConvBoolToInt";
|
||||
case EOpConvBoolToUint: return "EOpConvBoolToUint";
|
||||
case EOpConvBoolToInt64: return "EOpConvBoolToInt64";
|
||||
case EOpConvBoolToUint64: return "EOpConvBoolToUint64";
|
||||
case EOpConvBoolToFloat16: return "EOpConvBoolToFloat16";
|
||||
case EOpConvBoolToFloat: return "EOpConvBoolToFloat";
|
||||
case EOpConvBoolToDouble: return "EOpConvBoolToDouble";
|
||||
case EOpConvInt8ToInt16: return "EOpConvInt8ToInt16";
|
||||
case EOpConvInt8ToInt: return "EOpConvInt8ToInt";
|
||||
case EOpConvInt8ToInt64: return "EOpConvInt8ToInt64";
|
||||
case EOpConvInt8ToUint8: return "EOpConvInt8ToUint8";
|
||||
case EOpConvInt8ToUint16: return "EOpConvInt8ToUint16";
|
||||
case EOpConvInt8ToUint: return "EOpConvInt8ToUint";
|
||||
case EOpConvInt8ToUint64: return "EOpConvInt8ToUint64";
|
||||
case EOpConvUint8ToInt8: return "EOpConvUint8ToInt8";
|
||||
case EOpConvUint8ToInt16: return "EOpConvUint8ToInt16";
|
||||
case EOpConvUint8ToInt: return "EOpConvUint8ToInt";
|
||||
case EOpConvUint8ToInt64: return "EOpConvUint8ToInt64";
|
||||
case EOpConvUint8ToUint16: return "EOpConvUint8ToUint16";
|
||||
case EOpConvUint8ToUint: return "EOpConvUint8ToUint";
|
||||
case EOpConvUint8ToUint64: return "EOpConvUint8ToUint64";
|
||||
case EOpConvInt8ToFloat16: return "EOpConvInt8ToFloat16";
|
||||
case EOpConvInt8ToFloat: return "EOpConvInt8ToFloat";
|
||||
case EOpConvInt8ToDouble: return "EOpConvInt8ToDouble";
|
||||
case EOpConvUint8ToFloat16: return "EOpConvUint8ToFloat16";
|
||||
case EOpConvUint8ToFloat: return "EOpConvUint8ToFloat";
|
||||
case EOpConvUint8ToDouble: return "EOpConvUint8ToDouble";
|
||||
case EOpConvInt16ToInt8: return "EOpConvInt16ToInt8";
|
||||
case EOpConvInt16ToInt: return "EOpConvInt16ToInt";
|
||||
case EOpConvInt16ToInt64: return "EOpConvInt16ToInt64";
|
||||
case EOpConvInt16ToUint8: return "EOpConvInt16ToUint8";
|
||||
case EOpConvInt16ToUint16: return "EOpConvInt16ToUint16";
|
||||
case EOpConvInt16ToUint: return "EOpConvInt16ToUint";
|
||||
case EOpConvInt16ToUint64: return "EOpConvInt16ToUint64";
|
||||
case EOpConvUint16ToInt8: return "EOpConvUint16ToInt8";
|
||||
case EOpConvUint16ToInt16: return "EOpConvUint16ToInt16";
|
||||
case EOpConvUint16ToInt: return "EOpConvUint16ToInt";
|
||||
case EOpConvUint16ToInt64: return "EOpConvUint16ToInt64";
|
||||
case EOpConvUint16ToUint8: return "EOpConvUint16ToUint8";
|
||||
case EOpConvUint16ToUint: return "EOpConvUint16ToUint";
|
||||
case EOpConvUint16ToUint64: return "EOpConvUint16ToUint64";
|
||||
case EOpConvInt16ToFloat16: return "EOpConvInt16ToFloat16";
|
||||
case EOpConvInt16ToFloat: return "EOpConvInt16ToFloat";
|
||||
case EOpConvInt16ToDouble: return "EOpConvInt16ToDouble";
|
||||
case EOpConvUint16ToFloat16: return "EOpConvUint16ToFloat16";
|
||||
case EOpConvUint16ToFloat: return "EOpConvUint16ToFloat";
|
||||
case EOpConvUint16ToDouble: return "EOpConvUint16ToDouble";
|
||||
case EOpConvIntToInt8: return "EOpConvIntToInt8";
|
||||
case EOpConvIntToInt16: return "EOpConvIntToInt16";
|
||||
case EOpConvIntToInt64: return "EOpConvIntToInt64";
|
||||
case EOpConvIntToUint8: return "EOpConvIntToUint8";
|
||||
case EOpConvIntToUint16: return "EOpConvIntToUint16";
|
||||
case EOpConvIntToUint: return "EOpConvIntToUint";
|
||||
case EOpConvIntToUint64: return "EOpConvIntToUint64";
|
||||
case EOpConvUintToInt8: return "EOpConvUintToInt8";
|
||||
case EOpConvUintToInt16: return "EOpConvUintToInt16";
|
||||
case EOpConvUintToInt: return "EOpConvUintToInt";
|
||||
case EOpConvUintToInt64: return "EOpConvUintToInt64";
|
||||
case EOpConvUintToUint8: return "EOpConvUintToUint8";
|
||||
case EOpConvUintToUint16: return "EOpConvUintToUint16";
|
||||
case EOpConvUintToUint64: return "EOpConvUintToUint64";
|
||||
case EOpConvIntToFloat16: return "EOpConvIntToFloat16";
|
||||
case EOpConvIntToFloat: return "EOpConvIntToFloat";
|
||||
case EOpConvIntToDouble: return "EOpConvIntToDouble";
|
||||
case EOpConvUintToFloat16: return "EOpConvUintToFloat16";
|
||||
case EOpConvUintToFloat: return "EOpConvUintToFloat";
|
||||
case EOpConvUintToDouble: return "EOpConvUintToDouble";
|
||||
case EOpConvInt64ToInt8: return "EOpConvInt64ToInt8";
|
||||
case EOpConvInt64ToInt16: return "EOpConvInt64ToInt16";
|
||||
case EOpConvInt64ToInt: return "EOpConvInt64ToInt";
|
||||
case EOpConvInt64ToUint8: return "EOpConvInt64ToUint8";
|
||||
case EOpConvInt64ToUint16: return "EOpConvInt64ToUint16";
|
||||
case EOpConvInt64ToUint: return "EOpConvInt64ToUint";
|
||||
case EOpConvInt64ToUint64: return "EOpConvInt64ToUint64";
|
||||
case EOpConvUint64ToInt8: return "EOpConvUint64ToInt8";
|
||||
case EOpConvUint64ToInt16: return "EOpConvUint64ToInt16";
|
||||
case EOpConvUint64ToInt: return "EOpConvUint64ToInt";
|
||||
case EOpConvUint64ToInt64: return "EOpConvUint64ToInt64";
|
||||
case EOpConvUint64ToUint8: return "EOpConvUint64ToUint8";
|
||||
case EOpConvUint64ToUint16: return "EOpConvUint64ToUint16";
|
||||
case EOpConvUint64ToUint: return "EOpConvUint64ToUint";
|
||||
case EOpConvInt64ToFloat16: return "EOpConvInt64ToFloat16";
|
||||
case EOpConvInt64ToFloat: return "EOpConvInt64ToFloat";
|
||||
case EOpConvInt64ToDouble: return "EOpConvInt64ToDouble";
|
||||
case EOpConvUint64ToFloat16: return "EOpConvUint64ToFloat16";
|
||||
case EOpConvUint64ToFloat: return "EOpConvUint64ToFloat";
|
||||
case EOpConvUint64ToDouble: return "EOpConvUint64ToDouble";
|
||||
case EOpConvFloat16ToInt8: return "EOpConvFloat16ToInt8";
|
||||
case EOpConvFloat16ToInt16: return "EOpConvFloat16ToInt16";
|
||||
case EOpConvFloat16ToInt: return "EOpConvFloat16ToInt";
|
||||
case EOpConvFloat16ToInt64: return "EOpConvFloat16ToInt64";
|
||||
case EOpConvFloat16ToUint8: return "EOpConvFloat16ToUint8";
|
||||
case EOpConvFloat16ToUint16: return "EOpConvFloat16ToUint16";
|
||||
case EOpConvFloat16ToUint: return "EOpConvFloat16ToUint";
|
||||
case EOpConvFloat16ToUint64: return "EOpConvFloat16ToUint64";
|
||||
case EOpConvFloat16ToFloat: return "EOpConvFloat16ToFloat";
|
||||
case EOpConvFloat16ToDouble: return "EOpConvFloat16ToDouble";
|
||||
case EOpConvFloatToInt8: return "EOpConvFloatToInt8";
|
||||
case EOpConvFloatToInt16: return "EOpConvFloatToInt16";
|
||||
case EOpConvFloatToInt: return "EOpConvFloatToInt";
|
||||
case EOpConvFloatToInt64: return "EOpConvFloatToInt64";
|
||||
case EOpConvFloatToUint8: return "EOpConvFloatToUint8";
|
||||
case EOpConvFloatToUint16: return "EOpConvFloatToUint16";
|
||||
case EOpConvFloatToUint: return "EOpConvFloatToUint";
|
||||
case EOpConvFloatToUint64: return "EOpConvFloatToUint64";
|
||||
case EOpConvFloatToFloat16: return "EOpConvFloatToFloat16";
|
||||
case EOpConvFloatToDouble: return "EOpConvFloatToDouble";
|
||||
case EOpConvDoubleToInt8: return "EOpConvDoubleToInt8";
|
||||
case EOpConvDoubleToInt16: return "EOpConvDoubleToInt16";
|
||||
case EOpConvDoubleToInt: return "EOpConvDoubleToInt";
|
||||
case EOpConvDoubleToInt64: return "EOpConvDoubleToInt64";
|
||||
case EOpConvDoubleToUint8: return "EOpConvDoubleToUint8";
|
||||
case EOpConvDoubleToUint16: return "EOpConvDoubleToUint16";
|
||||
case EOpConvDoubleToUint: return "EOpConvDoubleToUint";
|
||||
case EOpConvDoubleToUint64: return "EOpConvDoubleToUint64";
|
||||
case EOpConvDoubleToFloat16: return "EOpConvDoubleToFloat16";
|
||||
case EOpConvDoubleToFloat: return "EOpConvDoubleToFloat";
|
||||
case EOpConvUint64ToPtr: return "EOpConvUint64ToPtr";
|
||||
case EOpConvPtrToUint64: return "EOpConvPtrToUint64";
|
||||
case EOpConvUvec2ToPtr: return "EOpConvUvec2ToPtr";
|
||||
case EOpConvPtrToUvec2: return "EOpConvPtrToUvec2";
|
||||
case EOpConvUint64ToAccStruct: return "EOpConvUint64ToAccStruct";
|
||||
case EOpConvUvec2ToAccStruct: return "EOpConvUvec2ToAccStruct";
|
||||
case EOpAdd: return "EOpAdd";
|
||||
case EOpSub: return "EOpSub";
|
||||
case EOpMul: return "EOpMul";
|
||||
case EOpDiv: return "EOpDiv";
|
||||
case EOpMod: return "EOpMod";
|
||||
case EOpRightShift: return "EOpRightShift";
|
||||
case EOpLeftShift: return "EOpLeftShift";
|
||||
case EOpAnd: return "EOpAnd";
|
||||
case EOpInclusiveOr: return "EOpInclusiveOr";
|
||||
case EOpExclusiveOr: return "EOpExclusiveOr";
|
||||
case EOpEqual: return "EOpEqual";
|
||||
case EOpNotEqual: return "EOpNotEqual";
|
||||
case EOpVectorEqual: return "EOpVectorEqual";
|
||||
case EOpVectorNotEqual: return "EOpVectorNotEqual";
|
||||
case EOpLessThan: return "EOpLessThan";
|
||||
case EOpGreaterThan: return "EOpGreaterThan";
|
||||
case EOpLessThanEqual: return "EOpLessThanEqual";
|
||||
case EOpGreaterThanEqual: return "EOpGreaterThanEqual";
|
||||
case EOpComma: return "EOpComma";
|
||||
case EOpVectorTimesScalar: return "EOpVectorTimesScalar";
|
||||
case EOpVectorTimesMatrix: return "EOpVectorTimesMatrix";
|
||||
case EOpMatrixTimesVector: return "EOpMatrixTimesVector";
|
||||
case EOpMatrixTimesScalar: return "EOpMatrixTimesScalar";
|
||||
case EOpLogicalOr: return "EOpLogicalOr";
|
||||
case EOpLogicalXor: return "EOpLogicalXor";
|
||||
case EOpLogicalAnd: return "EOpLogicalAnd";
|
||||
case EOpIndexDirect: return "EOpIndexDirect";
|
||||
case EOpIndexIndirect: return "EOpIndexIndirect";
|
||||
case EOpIndexDirectStruct: return "EOpIndexDirectStruct";
|
||||
case EOpVectorSwizzle: return "EOpVectorSwizzle";
|
||||
case EOpMethod: return "EOpMethod";
|
||||
case EOpScoping: return "EOpScoping";
|
||||
case EOpRadians: return "EOpRadians";
|
||||
case EOpDegrees: return "EOpDegrees";
|
||||
case EOpSin: return "EOpSin";
|
||||
case EOpCos: return "EOpCos";
|
||||
case EOpTan: return "EOpTan";
|
||||
case EOpAsin: return "EOpAsin";
|
||||
case EOpAcos: return "EOpAcos";
|
||||
case EOpAtan: return "EOpAtan";
|
||||
case EOpSinh: return "EOpSinh";
|
||||
case EOpCosh: return "EOpCosh";
|
||||
case EOpTanh: return "EOpTanh";
|
||||
case EOpAsinh: return "EOpAsinh";
|
||||
case EOpAcosh: return "EOpAcosh";
|
||||
case EOpAtanh: return "EOpAtanh";
|
||||
case EOpPow: return "EOpPow";
|
||||
case EOpExp: return "EOpExp";
|
||||
case EOpLog: return "EOpLog";
|
||||
case EOpExp2: return "EOpExp2";
|
||||
case EOpLog2: return "EOpLog2";
|
||||
case EOpSqrt: return "EOpSqrt";
|
||||
case EOpInverseSqrt: return "EOpInverseSqrt";
|
||||
case EOpAbs: return "EOpAbs";
|
||||
case EOpSign: return "EOpSign";
|
||||
case EOpFloor: return "EOpFloor";
|
||||
case EOpTrunc: return "EOpTrunc";
|
||||
case EOpRound: return "EOpRound";
|
||||
case EOpRoundEven: return "EOpRoundEven";
|
||||
case EOpCeil: return "EOpCeil";
|
||||
case EOpFract: return "EOpFract";
|
||||
case EOpModf: return "EOpModf";
|
||||
case EOpMin: return "EOpMin";
|
||||
case EOpMax: return "EOpMax";
|
||||
case EOpClamp: return "EOpClamp";
|
||||
case EOpMix: return "EOpMix";
|
||||
case EOpStep: return "EOpStep";
|
||||
case EOpSmoothStep: return "EOpSmoothStep";
|
||||
case EOpIsNan: return "EOpIsNan";
|
||||
case EOpIsInf: return "EOpIsInf";
|
||||
case EOpFma: return "EOpFma";
|
||||
case EOpFrexp: return "EOpFrexp";
|
||||
case EOpLdexp: return "EOpLdexp";
|
||||
case EOpFloatBitsToInt: return "EOpFloatBitsToInt";
|
||||
case EOpFloatBitsToUint: return "EOpFloatBitsToUint";
|
||||
case EOpIntBitsToFloat: return "EOpIntBitsToFloat";
|
||||
case EOpUintBitsToFloat: return "EOpUintBitsToFloat";
|
||||
case EOpDoubleBitsToInt64: return "EOpDoubleBitsToInt64";
|
||||
case EOpDoubleBitsToUint64: return "EOpDoubleBitsToUint64";
|
||||
case EOpInt64BitsToDouble: return "EOpInt64BitsToDouble";
|
||||
case EOpUint64BitsToDouble: return "EOpUint64BitsToDouble";
|
||||
case EOpFloat16BitsToInt16: return "EOpFloat16BitsToInt16";
|
||||
case EOpFloat16BitsToUint16: return "EOpFloat16BitsToUint16";
|
||||
case EOpInt16BitsToFloat16: return "EOpInt16BitsToFloat16";
|
||||
case EOpUint16BitsToFloat16: return "EOpUint16BitsToFloat16";
|
||||
case EOpPackSnorm2x16: return "EOpPackSnorm2x16";
|
||||
case EOpUnpackSnorm2x16: return "EOpUnpackSnorm2x16";
|
||||
case EOpPackUnorm2x16: return "EOpPackUnorm2x16";
|
||||
case EOpUnpackUnorm2x16: return "EOpUnpackUnorm2x16";
|
||||
case EOpPackSnorm4x8: return "EOpPackSnorm4x8";
|
||||
case EOpUnpackSnorm4x8: return "EOpUnpackSnorm4x8";
|
||||
case EOpPackUnorm4x8: return "EOpPackUnorm4x8";
|
||||
case EOpUnpackUnorm4x8: return "EOpUnpackUnorm4x8";
|
||||
case EOpPackHalf2x16: return "EOpPackHalf2x16";
|
||||
case EOpUnpackHalf2x16: return "EOpUnpackHalf2x16";
|
||||
case EOpPackDouble2x32: return "EOpPackDouble2x32";
|
||||
case EOpUnpackDouble2x32: return "EOpUnpackDouble2x32";
|
||||
case EOpPackInt2x32: return "EOpPackInt2x32";
|
||||
case EOpUnpackInt2x32: return "EOpUnpackInt2x32";
|
||||
case EOpPackUint2x32: return "EOpPackUint2x32";
|
||||
case EOpUnpackUint2x32: return "EOpUnpackUint2x32";
|
||||
case EOpPackFloat2x16: return "EOpPackFloat2x16";
|
||||
case EOpUnpackFloat2x16: return "EOpUnpackFloat2x16";
|
||||
case EOpPackInt2x16: return "EOpPackInt2x16";
|
||||
case EOpUnpackInt2x16: return "EOpUnpackInt2x16";
|
||||
case EOpPackUint2x16: return "EOpPackUint2x16";
|
||||
case EOpUnpackUint2x16: return "EOpUnpackUint2x16";
|
||||
case EOpPackInt4x16: return "EOpPackInt4x16";
|
||||
case EOpUnpackInt4x16: return "EOpUnpackInt4x16";
|
||||
case EOpPackUint4x16: return "EOpPackUint4x16";
|
||||
case EOpUnpackUint4x16: return "EOpUnpackUint4x16";
|
||||
case EOpPack16: return "EOpPack16";
|
||||
case EOpPack32: return "EOpPack32";
|
||||
case EOpPack64: return "EOpPack64";
|
||||
case EOpUnpack32: return "EOpUnpack32";
|
||||
case EOpUnpack16: return "EOpUnpack16";
|
||||
case EOpUnpack8: return "EOpUnpack8";
|
||||
case EOpLength: return "EOpLength";
|
||||
case EOpDistance: return "EOpDistance";
|
||||
case EOpDot: return "EOpDot";
|
||||
case EOpCross: return "EOpCross";
|
||||
case EOpNormalize: return "EOpNormalize";
|
||||
case EOpFaceForward: return "EOpFaceForward";
|
||||
case EOpReflect: return "EOpReflect";
|
||||
case EOpRefract: return "EOpRefract";
|
||||
case EOpMin3: return "EOpMin3";
|
||||
case EOpMax3: return "EOpMax3";
|
||||
case EOpMid3: return "EOpMid3";
|
||||
case EOpDPdx: return "EOpDPdx";
|
||||
case EOpDPdy: return "EOpDPdy";
|
||||
case EOpFwidth: return "EOpFwidth";
|
||||
case EOpDPdxFine: return "EOpDPdxFine";
|
||||
case EOpDPdyFine: return "EOpDPdyFine";
|
||||
case EOpFwidthFine: return "EOpFwidthFine";
|
||||
case EOpDPdxCoarse: return "EOpDPdxCoarse";
|
||||
case EOpDPdyCoarse: return "EOpDPdyCoarse";
|
||||
case EOpFwidthCoarse: return "EOpFwidthCoarse";
|
||||
case EOpInterpolateAtCentroid: return "EOpInterpolateAtCentroid";
|
||||
case EOpInterpolateAtSample: return "EOpInterpolateAtSample";
|
||||
case EOpInterpolateAtOffset: return "EOpInterpolateAtOffset";
|
||||
case EOpInterpolateAtVertex: return "EOpInterpolateAtVertex";
|
||||
case EOpMatrixTimesMatrix: return "EOpMatrixTimesMatrix";
|
||||
case EOpOuterProduct: return "EOpOuterProduct";
|
||||
case EOpDeterminant: return "EOpDeterminant";
|
||||
case EOpMatrixInverse: return "EOpMatrixInverse";
|
||||
case EOpTranspose: return "EOpTranspose";
|
||||
case EOpFtransform: return "EOpFtransform";
|
||||
case EOpNoise: return "EOpNoise";
|
||||
case EOpEmitVertex: return "EOpEmitVertex";
|
||||
case EOpEndPrimitive: return "EOpEndPrimitive";
|
||||
case EOpEmitStreamVertex: return "EOpEmitStreamVertex";
|
||||
case EOpEndStreamPrimitive: return "EOpEndStreamPrimitive";
|
||||
case EOpBarrier: return "EOpBarrier";
|
||||
case EOpMemoryBarrier: return "EOpMemoryBarrier";
|
||||
case EOpMemoryBarrierAtomicCounter: return "EOpMemoryBarrierAtomicCounter";
|
||||
case EOpMemoryBarrierBuffer: return "EOpMemoryBarrierBuffer";
|
||||
case EOpMemoryBarrierImage: return "EOpMemoryBarrierImage";
|
||||
case EOpMemoryBarrierShared: return "EOpMemoryBarrierShared";
|
||||
case EOpGroupMemoryBarrier: return "EOpGroupMemoryBarrier";
|
||||
case EOpBallot: return "EOpBallot";
|
||||
case EOpReadInvocation: return "EOpReadInvocation";
|
||||
case EOpReadFirstInvocation: return "EOpReadFirstInvocation";
|
||||
case EOpAnyInvocation: return "EOpAnyInvocation";
|
||||
case EOpAllInvocations: return "EOpAllInvocations";
|
||||
case EOpAllInvocationsEqual: return "EOpAllInvocationsEqual";
|
||||
case EOpSubgroupGuardStart: return "EOpSubgroupGuardStart";
|
||||
case EOpSubgroupBarrier: return "EOpSubgroupBarrier";
|
||||
case EOpSubgroupMemoryBarrier: return "EOpSubgroupMemoryBarrier";
|
||||
case EOpSubgroupMemoryBarrierBuffer: return "EOpSubgroupMemoryBarrierBuffer";
|
||||
case EOpSubgroupMemoryBarrierImage: return "EOpSubgroupMemoryBarrierImage";
|
||||
case EOpSubgroupMemoryBarrierShared: return "EOpSubgroupMemoryBarrierShared";
|
||||
case EOpSubgroupElect: return "EOpSubgroupElect";
|
||||
case EOpSubgroupAll: return "EOpSubgroupAll";
|
||||
case EOpSubgroupAny: return "EOpSubgroupAny";
|
||||
case EOpSubgroupAllEqual: return "EOpSubgroupAllEqual";
|
||||
case EOpSubgroupBroadcast: return "EOpSubgroupBroadcast";
|
||||
case EOpSubgroupBroadcastFirst: return "EOpSubgroupBroadcastFirst";
|
||||
case EOpSubgroupBallot: return "EOpSubgroupBallot";
|
||||
case EOpSubgroupInverseBallot: return "EOpSubgroupInverseBallot";
|
||||
case EOpSubgroupBallotBitExtract: return "EOpSubgroupBallotBitExtract";
|
||||
case EOpSubgroupBallotBitCount: return "EOpSubgroupBallotBitCount";
|
||||
case EOpSubgroupBallotInclusiveBitCount: return "EOpSubgroupBallotInclusiveBitCount";
|
||||
case EOpSubgroupBallotExclusiveBitCount: return "EOpSubgroupBallotExclusiveBitCount";
|
||||
case EOpSubgroupBallotFindLSB: return "EOpSubgroupBallotFindLSB";
|
||||
case EOpSubgroupBallotFindMSB: return "EOpSubgroupBallotFindMSB";
|
||||
case EOpSubgroupShuffle: return "EOpSubgroupShuffle";
|
||||
case EOpSubgroupShuffleXor: return "EOpSubgroupShuffleXor";
|
||||
case EOpSubgroupShuffleUp: return "EOpSubgroupShuffleUp";
|
||||
case EOpSubgroupShuffleDown: return "EOpSubgroupShuffleDown";
|
||||
case EOpSubgroupAdd: return "EOpSubgroupAdd";
|
||||
case EOpSubgroupMul: return "EOpSubgroupMul";
|
||||
case EOpSubgroupMin: return "EOpSubgroupMin";
|
||||
case EOpSubgroupMax: return "EOpSubgroupMax";
|
||||
case EOpSubgroupAnd: return "EOpSubgroupAnd";
|
||||
case EOpSubgroupOr: return "EOpSubgroupOr";
|
||||
case EOpSubgroupXor: return "EOpSubgroupXor";
|
||||
case EOpSubgroupInclusiveAdd: return "EOpSubgroupInclusiveAdd";
|
||||
case EOpSubgroupInclusiveMul: return "EOpSubgroupInclusiveMul";
|
||||
case EOpSubgroupInclusiveMin: return "EOpSubgroupInclusiveMin";
|
||||
case EOpSubgroupInclusiveMax: return "EOpSubgroupInclusiveMax";
|
||||
case EOpSubgroupInclusiveAnd: return "EOpSubgroupInclusiveAnd";
|
||||
case EOpSubgroupInclusiveOr: return "EOpSubgroupInclusiveOr";
|
||||
case EOpSubgroupInclusiveXor: return "EOpSubgroupInclusiveXor";
|
||||
case EOpSubgroupExclusiveAdd: return "EOpSubgroupExclusiveAdd";
|
||||
case EOpSubgroupExclusiveMul: return "EOpSubgroupExclusiveMul";
|
||||
case EOpSubgroupExclusiveMin: return "EOpSubgroupExclusiveMin";
|
||||
case EOpSubgroupExclusiveMax: return "EOpSubgroupExclusiveMax";
|
||||
case EOpSubgroupExclusiveAnd: return "EOpSubgroupExclusiveAnd";
|
||||
case EOpSubgroupExclusiveOr: return "EOpSubgroupExclusiveOr";
|
||||
case EOpSubgroupExclusiveXor: return "EOpSubgroupExclusiveXor";
|
||||
case EOpSubgroupClusteredAdd: return "EOpSubgroupClusteredAdd";
|
||||
case EOpSubgroupClusteredMul: return "EOpSubgroupClusteredMul";
|
||||
case EOpSubgroupClusteredMin: return "EOpSubgroupClusteredMin";
|
||||
case EOpSubgroupClusteredMax: return "EOpSubgroupClusteredMax";
|
||||
case EOpSubgroupClusteredAnd: return "EOpSubgroupClusteredAnd";
|
||||
case EOpSubgroupClusteredOr: return "EOpSubgroupClusteredOr";
|
||||
case EOpSubgroupClusteredXor: return "EOpSubgroupClusteredXor";
|
||||
case EOpSubgroupQuadBroadcast: return "EOpSubgroupQuadBroadcast";
|
||||
case EOpSubgroupQuadSwapHorizontal: return "EOpSubgroupQuadSwapHorizontal";
|
||||
case EOpSubgroupQuadSwapVertical: return "EOpSubgroupQuadSwapVertical";
|
||||
case EOpSubgroupQuadSwapDiagonal: return "EOpSubgroupQuadSwapDiagonal";
|
||||
case EOpSubgroupPartition: return "EOpSubgroupPartition";
|
||||
case EOpSubgroupPartitionedAdd: return "EOpSubgroupPartitionedAdd";
|
||||
case EOpSubgroupPartitionedMul: return "EOpSubgroupPartitionedMul";
|
||||
case EOpSubgroupPartitionedMin: return "EOpSubgroupPartitionedMin";
|
||||
case EOpSubgroupPartitionedMax: return "EOpSubgroupPartitionedMax";
|
||||
case EOpSubgroupPartitionedAnd: return "EOpSubgroupPartitionedAnd";
|
||||
case EOpSubgroupPartitionedOr: return "EOpSubgroupPartitionedOr";
|
||||
case EOpSubgroupPartitionedXor: return "EOpSubgroupPartitionedXor";
|
||||
case EOpSubgroupPartitionedInclusiveAdd: return "EOpSubgroupPartitionedInclusiveAdd";
|
||||
case EOpSubgroupPartitionedInclusiveMul: return "EOpSubgroupPartitionedInclusiveMul";
|
||||
case EOpSubgroupPartitionedInclusiveMin: return "EOpSubgroupPartitionedInclusiveMin";
|
||||
case EOpSubgroupPartitionedInclusiveMax: return "EOpSubgroupPartitionedInclusiveMax";
|
||||
case EOpSubgroupPartitionedInclusiveAnd: return "EOpSubgroupPartitionedInclusiveAnd";
|
||||
case EOpSubgroupPartitionedInclusiveOr: return "EOpSubgroupPartitionedInclusiveOr";
|
||||
case EOpSubgroupPartitionedInclusiveXor: return "EOpSubgroupPartitionedInclusiveXor";
|
||||
case EOpSubgroupPartitionedExclusiveAdd: return "EOpSubgroupPartitionedExclusiveAdd";
|
||||
case EOpSubgroupPartitionedExclusiveMul: return "EOpSubgroupPartitionedExclusiveMul";
|
||||
case EOpSubgroupPartitionedExclusiveMin: return "EOpSubgroupPartitionedExclusiveMin";
|
||||
case EOpSubgroupPartitionedExclusiveMax: return "EOpSubgroupPartitionedExclusiveMax";
|
||||
case EOpSubgroupPartitionedExclusiveAnd: return "EOpSubgroupPartitionedExclusiveAnd";
|
||||
case EOpSubgroupPartitionedExclusiveOr: return "EOpSubgroupPartitionedExclusiveOr";
|
||||
case EOpSubgroupPartitionedExclusiveXor: return "EOpSubgroupPartitionedExclusiveXor";
|
||||
case EOpSubgroupGuardStop: return "EOpSubgroupGuardStop";
|
||||
case EOpMinInvocations: return "EOpMinInvocations";
|
||||
case EOpMaxInvocations: return "EOpMaxInvocations";
|
||||
case EOpAddInvocations: return "EOpAddInvocations";
|
||||
case EOpMinInvocationsNonUniform: return "EOpMinInvocationsNonUniform";
|
||||
case EOpMaxInvocationsNonUniform: return "EOpMaxInvocationsNonUniform";
|
||||
case EOpAddInvocationsNonUniform: return "EOpAddInvocationsNonUniform";
|
||||
case EOpMinInvocationsInclusiveScan: return "EOpMinInvocationsInclusiveScan";
|
||||
case EOpMaxInvocationsInclusiveScan: return "EOpMaxInvocationsInclusiveScan";
|
||||
case EOpAddInvocationsInclusiveScan: return "EOpAddInvocationsInclusiveScan";
|
||||
case EOpMinInvocationsInclusiveScanNonUniform: return "EOpMinInvocationsInclusiveScanNonUniform";
|
||||
case EOpMaxInvocationsInclusiveScanNonUniform: return "EOpMaxInvocationsInclusiveScanNonUniform";
|
||||
case EOpAddInvocationsInclusiveScanNonUniform: return "EOpAddInvocationsInclusiveScanNonUniform";
|
||||
case EOpMinInvocationsExclusiveScan: return "EOpMinInvocationsExclusiveScan";
|
||||
case EOpMaxInvocationsExclusiveScan: return "EOpMaxInvocationsExclusiveScan";
|
||||
case EOpAddInvocationsExclusiveScan: return "EOpAddInvocationsExclusiveScan";
|
||||
case EOpMinInvocationsExclusiveScanNonUniform: return "EOpMinInvocationsExclusiveScanNonUniform";
|
||||
case EOpMaxInvocationsExclusiveScanNonUniform: return "EOpMaxInvocationsExclusiveScanNonUniform";
|
||||
case EOpAddInvocationsExclusiveScanNonUniform: return "EOpAddInvocationsExclusiveScanNonUniform";
|
||||
case EOpSwizzleInvocations: return "EOpSwizzleInvocations";
|
||||
case EOpSwizzleInvocationsMasked: return "EOpSwizzleInvocationsMasked";
|
||||
case EOpWriteInvocation: return "EOpWriteInvocation";
|
||||
case EOpMbcnt: return "EOpMbcnt";
|
||||
case EOpCubeFaceIndex: return "EOpCubeFaceIndex";
|
||||
case EOpCubeFaceCoord: return "EOpCubeFaceCoord";
|
||||
case EOpTime: return "EOpTime";
|
||||
case EOpAtomicAdd: return "EOpAtomicAdd";
|
||||
case EOpAtomicSubtract: return "EOpAtomicSubtract";
|
||||
case EOpAtomicMin: return "EOpAtomicMin";
|
||||
case EOpAtomicMax: return "EOpAtomicMax";
|
||||
case EOpAtomicAnd: return "EOpAtomicAnd";
|
||||
case EOpAtomicOr: return "EOpAtomicOr";
|
||||
case EOpAtomicXor: return "EOpAtomicXor";
|
||||
case EOpAtomicExchange: return "EOpAtomicExchange";
|
||||
case EOpAtomicCompSwap: return "EOpAtomicCompSwap";
|
||||
case EOpAtomicLoad: return "EOpAtomicLoad";
|
||||
case EOpAtomicStore: return "EOpAtomicStore";
|
||||
case EOpAtomicCounterIncrement: return "EOpAtomicCounterIncrement";
|
||||
case EOpAtomicCounterDecrement: return "EOpAtomicCounterDecrement";
|
||||
case EOpAtomicCounter: return "EOpAtomicCounter";
|
||||
case EOpAtomicCounterAdd: return "EOpAtomicCounterAdd";
|
||||
case EOpAtomicCounterSubtract: return "EOpAtomicCounterSubtract";
|
||||
case EOpAtomicCounterMin: return "EOpAtomicCounterMin";
|
||||
case EOpAtomicCounterMax: return "EOpAtomicCounterMax";
|
||||
case EOpAtomicCounterAnd: return "EOpAtomicCounterAnd";
|
||||
case EOpAtomicCounterOr: return "EOpAtomicCounterOr";
|
||||
case EOpAtomicCounterXor: return "EOpAtomicCounterXor";
|
||||
case EOpAtomicCounterExchange: return "EOpAtomicCounterExchange";
|
||||
case EOpAtomicCounterCompSwap: return "EOpAtomicCounterCompSwap";
|
||||
case EOpAny: return "EOpAny";
|
||||
case EOpAll: return "EOpAll";
|
||||
case EOpCooperativeMatrixLoad: return "EOpCooperativeMatrixLoad";
|
||||
case EOpCooperativeMatrixStore: return "EOpCooperativeMatrixStore";
|
||||
case EOpCooperativeMatrixMulAdd: return "EOpCooperativeMatrixMulAdd";
|
||||
case EOpCooperativeMatrixLoadNV: return "EOpCooperativeMatrixLoadNV";
|
||||
case EOpCooperativeMatrixStoreNV: return "EOpCooperativeMatrixStoreNV";
|
||||
case EOpCooperativeMatrixMulAddNV: return "EOpCooperativeMatrixMulAddNV";
|
||||
case EOpBeginInvocationInterlock: return "EOpBeginInvocationInterlock";
|
||||
case EOpEndInvocationInterlock: return "EOpEndInvocationInterlock";
|
||||
case EOpIsHelperInvocation: return "EOpIsHelperInvocation";
|
||||
case EOpDebugPrintf: return "EOpDebugPrintf";
|
||||
case EOpKill: return "EOpKill";
|
||||
case EOpTerminateInvocation: return "EOpTerminateInvocation";
|
||||
case EOpDemote: return "EOpDemote";
|
||||
case EOpTerminateRayKHR: return "EOpTerminateRayKHR";
|
||||
case EOpIgnoreIntersectionKHR: return "EOpIgnoreIntersectionKHR";
|
||||
case EOpReturn: return "EOpReturn";
|
||||
case EOpBreak: return "EOpBreak";
|
||||
case EOpContinue: return "EOpContinue";
|
||||
case EOpCase: return "EOpCase";
|
||||
case EOpDefault: return "EOpDefault";
|
||||
case EOpConstructGuardStart: return "EOpConstructGuardStart";
|
||||
case EOpConstructInt: return "EOpConstructInt";
|
||||
case EOpConstructUint: return "EOpConstructUint";
|
||||
case EOpConstructInt8: return "EOpConstructInt8";
|
||||
case EOpConstructUint8: return "EOpConstructUint8";
|
||||
case EOpConstructInt16: return "EOpConstructInt16";
|
||||
case EOpConstructUint16: return "EOpConstructUint16";
|
||||
case EOpConstructInt64: return "EOpConstructInt64";
|
||||
case EOpConstructUint64: return "EOpConstructUint64";
|
||||
case EOpConstructBool: return "EOpConstructBool";
|
||||
case EOpConstructFloat: return "EOpConstructFloat";
|
||||
case EOpConstructDouble: return "EOpConstructDouble";
|
||||
case EOpConstructVec2: return "EOpConstructVec2";
|
||||
case EOpConstructVec3: return "EOpConstructVec3";
|
||||
case EOpConstructVec4: return "EOpConstructVec4";
|
||||
case EOpConstructMat2x2: return "EOpConstructMat2x2";
|
||||
case EOpConstructMat2x3: return "EOpConstructMat2x3";
|
||||
case EOpConstructMat2x4: return "EOpConstructMat2x4";
|
||||
case EOpConstructMat3x2: return "EOpConstructMat3x2";
|
||||
case EOpConstructMat3x3: return "EOpConstructMat3x3";
|
||||
case EOpConstructMat3x4: return "EOpConstructMat3x4";
|
||||
case EOpConstructMat4x2: return "EOpConstructMat4x2";
|
||||
case EOpConstructMat4x3: return "EOpConstructMat4x3";
|
||||
case EOpConstructMat4x4: return "EOpConstructMat4x4";
|
||||
case EOpConstructDVec2: return "EOpConstructDVec2";
|
||||
case EOpConstructDVec3: return "EOpConstructDVec3";
|
||||
case EOpConstructDVec4: return "EOpConstructDVec4";
|
||||
case EOpConstructBVec2: return "EOpConstructBVec2";
|
||||
case EOpConstructBVec3: return "EOpConstructBVec3";
|
||||
case EOpConstructBVec4: return "EOpConstructBVec4";
|
||||
case EOpConstructI8Vec2: return "EOpConstructI8Vec2";
|
||||
case EOpConstructI8Vec3: return "EOpConstructI8Vec3";
|
||||
case EOpConstructI8Vec4: return "EOpConstructI8Vec4";
|
||||
case EOpConstructU8Vec2: return "EOpConstructU8Vec2";
|
||||
case EOpConstructU8Vec3: return "EOpConstructU8Vec3";
|
||||
case EOpConstructU8Vec4: return "EOpConstructU8Vec4";
|
||||
case EOpConstructI16Vec2: return "EOpConstructI16Vec2";
|
||||
case EOpConstructI16Vec3: return "EOpConstructI16Vec3";
|
||||
case EOpConstructI16Vec4: return "EOpConstructI16Vec4";
|
||||
case EOpConstructU16Vec2: return "EOpConstructU16Vec2";
|
||||
case EOpConstructU16Vec3: return "EOpConstructU16Vec3";
|
||||
case EOpConstructU16Vec4: return "EOpConstructU16Vec4";
|
||||
case EOpConstructIVec2: return "EOpConstructIVec2";
|
||||
case EOpConstructIVec3: return "EOpConstructIVec3";
|
||||
case EOpConstructIVec4: return "EOpConstructIVec4";
|
||||
case EOpConstructUVec2: return "EOpConstructUVec2";
|
||||
case EOpConstructUVec3: return "EOpConstructUVec3";
|
||||
case EOpConstructUVec4: return "EOpConstructUVec4";
|
||||
case EOpConstructI64Vec2: return "EOpConstructI64Vec2";
|
||||
case EOpConstructI64Vec3: return "EOpConstructI64Vec3";
|
||||
case EOpConstructI64Vec4: return "EOpConstructI64Vec4";
|
||||
case EOpConstructU64Vec2: return "EOpConstructU64Vec2";
|
||||
case EOpConstructU64Vec3: return "EOpConstructU64Vec3";
|
||||
case EOpConstructU64Vec4: return "EOpConstructU64Vec4";
|
||||
case EOpConstructDMat2x2: return "EOpConstructDMat2x2";
|
||||
case EOpConstructDMat2x3: return "EOpConstructDMat2x3";
|
||||
case EOpConstructDMat2x4: return "EOpConstructDMat2x4";
|
||||
case EOpConstructDMat3x2: return "EOpConstructDMat3x2";
|
||||
case EOpConstructDMat3x3: return "EOpConstructDMat3x3";
|
||||
case EOpConstructDMat3x4: return "EOpConstructDMat3x4";
|
||||
case EOpConstructDMat4x2: return "EOpConstructDMat4x2";
|
||||
case EOpConstructDMat4x3: return "EOpConstructDMat4x3";
|
||||
case EOpConstructDMat4x4: return "EOpConstructDMat4x4";
|
||||
case EOpConstructIMat2x2: return "EOpConstructIMat2x2";
|
||||
case EOpConstructIMat2x3: return "EOpConstructIMat2x3";
|
||||
case EOpConstructIMat2x4: return "EOpConstructIMat2x4";
|
||||
case EOpConstructIMat3x2: return "EOpConstructIMat3x2";
|
||||
case EOpConstructIMat3x3: return "EOpConstructIMat3x3";
|
||||
case EOpConstructIMat3x4: return "EOpConstructIMat3x4";
|
||||
case EOpConstructIMat4x2: return "EOpConstructIMat4x2";
|
||||
case EOpConstructIMat4x3: return "EOpConstructIMat4x3";
|
||||
case EOpConstructIMat4x4: return "EOpConstructIMat4x4";
|
||||
case EOpConstructUMat2x2: return "EOpConstructUMat2x2";
|
||||
case EOpConstructUMat2x3: return "EOpConstructUMat2x3";
|
||||
case EOpConstructUMat2x4: return "EOpConstructUMat2x4";
|
||||
case EOpConstructUMat3x2: return "EOpConstructUMat3x2";
|
||||
case EOpConstructUMat3x3: return "EOpConstructUMat3x3";
|
||||
case EOpConstructUMat3x4: return "EOpConstructUMat3x4";
|
||||
case EOpConstructUMat4x2: return "EOpConstructUMat4x2";
|
||||
case EOpConstructUMat4x3: return "EOpConstructUMat4x3";
|
||||
case EOpConstructUMat4x4: return "EOpConstructUMat4x4";
|
||||
case EOpConstructBMat2x2: return "EOpConstructBMat2x2";
|
||||
case EOpConstructBMat2x3: return "EOpConstructBMat2x3";
|
||||
case EOpConstructBMat2x4: return "EOpConstructBMat2x4";
|
||||
case EOpConstructBMat3x2: return "EOpConstructBMat3x2";
|
||||
case EOpConstructBMat3x3: return "EOpConstructBMat3x3";
|
||||
case EOpConstructBMat3x4: return "EOpConstructBMat3x4";
|
||||
case EOpConstructBMat4x2: return "EOpConstructBMat4x2";
|
||||
case EOpConstructBMat4x3: return "EOpConstructBMat4x3";
|
||||
case EOpConstructBMat4x4: return "EOpConstructBMat4x4";
|
||||
case EOpConstructFloat16: return "EOpConstructFloat16";
|
||||
case EOpConstructF16Vec2: return "EOpConstructF16Vec2";
|
||||
case EOpConstructF16Vec3: return "EOpConstructF16Vec3";
|
||||
case EOpConstructF16Vec4: return "EOpConstructF16Vec4";
|
||||
case EOpConstructF16Mat2x2: return "EOpConstructF16Mat2x2";
|
||||
case EOpConstructF16Mat2x3: return "EOpConstructF16Mat2x3";
|
||||
case EOpConstructF16Mat2x4: return "EOpConstructF16Mat2x4";
|
||||
case EOpConstructF16Mat3x2: return "EOpConstructF16Mat3x2";
|
||||
case EOpConstructF16Mat3x3: return "EOpConstructF16Mat3x3";
|
||||
case EOpConstructF16Mat3x4: return "EOpConstructF16Mat3x4";
|
||||
case EOpConstructF16Mat4x2: return "EOpConstructF16Mat4x2";
|
||||
case EOpConstructF16Mat4x3: return "EOpConstructF16Mat4x3";
|
||||
case EOpConstructF16Mat4x4: return "EOpConstructF16Mat4x4";
|
||||
case EOpConstructStruct: return "EOpConstructStruct";
|
||||
case EOpConstructTextureSampler: return "EOpConstructTextureSampler";
|
||||
case EOpConstructNonuniform: return "EOpConstructNonuniform";
|
||||
case EOpConstructReference: return "EOpConstructReference";
|
||||
case EOpConstructCooperativeMatrixNV: return "EOpConstructCooperativeMatrixNV";
|
||||
case EOpConstructCooperativeMatrixKHR: return "EOpConstructCooperativeMatrixKHR";
|
||||
case EOpConstructAccStruct: return "EOpConstructAccStruct";
|
||||
case EOpConstructGuardEnd: return "EOpConstructGuardEnd";
|
||||
case EOpAssign: return "EOpAssign";
|
||||
case EOpAddAssign: return "EOpAddAssign";
|
||||
case EOpSubAssign: return "EOpSubAssign";
|
||||
case EOpMulAssign: return "EOpMulAssign";
|
||||
case EOpVectorTimesMatrixAssign: return "EOpVectorTimesMatrixAssign";
|
||||
case EOpVectorTimesScalarAssign: return "EOpVectorTimesScalarAssign";
|
||||
case EOpMatrixTimesScalarAssign: return "EOpMatrixTimesScalarAssign";
|
||||
case EOpMatrixTimesMatrixAssign: return "EOpMatrixTimesMatrixAssign";
|
||||
case EOpDivAssign: return "EOpDivAssign";
|
||||
case EOpModAssign: return "EOpModAssign";
|
||||
case EOpAndAssign: return "EOpAndAssign";
|
||||
case EOpInclusiveOrAssign: return "EOpInclusiveOrAssign";
|
||||
case EOpExclusiveOrAssign: return "EOpExclusiveOrAssign";
|
||||
case EOpLeftShiftAssign: return "EOpLeftShiftAssign";
|
||||
case EOpRightShiftAssign: return "EOpRightShiftAssign";
|
||||
case EOpArrayLength: return "EOpArrayLength";
|
||||
case EOpImageGuardBegin: return "EOpImageGuardBegin";
|
||||
case EOpImageQuerySize: return "EOpImageQuerySize";
|
||||
case EOpImageQuerySamples: return "EOpImageQuerySamples";
|
||||
case EOpImageLoad: return "EOpImageLoad";
|
||||
case EOpImageStore: return "EOpImageStore";
|
||||
case EOpImageLoadLod: return "EOpImageLoadLod";
|
||||
case EOpImageStoreLod: return "EOpImageStoreLod";
|
||||
case EOpImageAtomicAdd: return "EOpImageAtomicAdd";
|
||||
case EOpImageAtomicMin: return "EOpImageAtomicMin";
|
||||
case EOpImageAtomicMax: return "EOpImageAtomicMax";
|
||||
case EOpImageAtomicAnd: return "EOpImageAtomicAnd";
|
||||
case EOpImageAtomicOr: return "EOpImageAtomicOr";
|
||||
case EOpImageAtomicXor: return "EOpImageAtomicXor";
|
||||
case EOpImageAtomicExchange: return "EOpImageAtomicExchange";
|
||||
case EOpImageAtomicCompSwap: return "EOpImageAtomicCompSwap";
|
||||
case EOpImageAtomicLoad: return "EOpImageAtomicLoad";
|
||||
case EOpImageAtomicStore: return "EOpImageAtomicStore";
|
||||
case EOpSubpassLoad: return "EOpSubpassLoad";
|
||||
case EOpSubpassLoadMS: return "EOpSubpassLoadMS";
|
||||
case EOpSparseImageLoad: return "EOpSparseImageLoad";
|
||||
case EOpSparseImageLoadLod: return "EOpSparseImageLoadLod";
|
||||
case EOpColorAttachmentReadEXT: return "EOpColorAttachmentReadEXT";
|
||||
case EOpImageGuardEnd: return "EOpImageGuardEnd";
|
||||
case EOpTextureGuardBegin: return "EOpTextureGuardBegin";
|
||||
case EOpTextureQuerySize: return "EOpTextureQuerySize";
|
||||
case EOpTextureQueryLod: return "EOpTextureQueryLod";
|
||||
case EOpTextureQueryLevels: return "EOpTextureQueryLevels";
|
||||
case EOpTextureQuerySamples: return "EOpTextureQuerySamples";
|
||||
case EOpSamplingGuardBegin: return "EOpSamplingGuardBegin";
|
||||
case EOpTexture: return "EOpTexture";
|
||||
case EOpTextureProj: return "EOpTextureProj";
|
||||
case EOpTextureLod: return "EOpTextureLod";
|
||||
case EOpTextureOffset: return "EOpTextureOffset";
|
||||
case EOpTextureFetch: return "EOpTextureFetch";
|
||||
case EOpTextureFetchOffset: return "EOpTextureFetchOffset";
|
||||
case EOpTextureProjOffset: return "EOpTextureProjOffset";
|
||||
case EOpTextureLodOffset: return "EOpTextureLodOffset";
|
||||
case EOpTextureProjLod: return "EOpTextureProjLod";
|
||||
case EOpTextureProjLodOffset: return "EOpTextureProjLodOffset";
|
||||
case EOpTextureGrad: return "EOpTextureGrad";
|
||||
case EOpTextureGradOffset: return "EOpTextureGradOffset";
|
||||
case EOpTextureProjGrad: return "EOpTextureProjGrad";
|
||||
case EOpTextureProjGradOffset: return "EOpTextureProjGradOffset";
|
||||
case EOpTextureGather: return "EOpTextureGather";
|
||||
case EOpTextureGatherOffset: return "EOpTextureGatherOffset";
|
||||
case EOpTextureGatherOffsets: return "EOpTextureGatherOffsets";
|
||||
case EOpTextureClamp: return "EOpTextureClamp";
|
||||
case EOpTextureOffsetClamp: return "EOpTextureOffsetClamp";
|
||||
case EOpTextureGradClamp: return "EOpTextureGradClamp";
|
||||
case EOpTextureGradOffsetClamp: return "EOpTextureGradOffsetClamp";
|
||||
case EOpTextureGatherLod: return "EOpTextureGatherLod";
|
||||
case EOpTextureGatherLodOffset: return "EOpTextureGatherLodOffset";
|
||||
case EOpTextureGatherLodOffsets: return "EOpTextureGatherLodOffsets";
|
||||
case EOpFragmentMaskFetch: return "EOpFragmentMaskFetch";
|
||||
case EOpFragmentFetch: return "EOpFragmentFetch";
|
||||
case EOpSparseTextureGuardBegin: return "EOpSparseTextureGuardBegin";
|
||||
case EOpSparseTexture: return "EOpSparseTexture";
|
||||
case EOpSparseTextureLod: return "EOpSparseTextureLod";
|
||||
case EOpSparseTextureOffset: return "EOpSparseTextureOffset";
|
||||
case EOpSparseTextureFetch: return "EOpSparseTextureFetch";
|
||||
case EOpSparseTextureFetchOffset: return "EOpSparseTextureFetchOffset";
|
||||
case EOpSparseTextureLodOffset: return "EOpSparseTextureLodOffset";
|
||||
case EOpSparseTextureGrad: return "EOpSparseTextureGrad";
|
||||
case EOpSparseTextureGradOffset: return "EOpSparseTextureGradOffset";
|
||||
case EOpSparseTextureGather: return "EOpSparseTextureGather";
|
||||
case EOpSparseTextureGatherOffset: return "EOpSparseTextureGatherOffset";
|
||||
case EOpSparseTextureGatherOffsets: return "EOpSparseTextureGatherOffsets";
|
||||
case EOpSparseTexelsResident: return "EOpSparseTexelsResident";
|
||||
case EOpSparseTextureClamp: return "EOpSparseTextureClamp";
|
||||
case EOpSparseTextureOffsetClamp: return "EOpSparseTextureOffsetClamp";
|
||||
case EOpSparseTextureGradClamp: return "EOpSparseTextureGradClamp";
|
||||
case EOpSparseTextureGradOffsetClamp: return "EOpSparseTextureGradOffsetClamp";
|
||||
case EOpSparseTextureGatherLod: return "EOpSparseTextureGatherLod";
|
||||
case EOpSparseTextureGatherLodOffset: return "EOpSparseTextureGatherLodOffset";
|
||||
case EOpSparseTextureGatherLodOffsets: return "EOpSparseTextureGatherLodOffsets";
|
||||
case EOpSparseTextureGuardEnd: return "EOpSparseTextureGuardEnd";
|
||||
case EOpImageFootprintGuardBegin: return "EOpImageFootprintGuardBegin";
|
||||
case EOpImageSampleFootprintNV: return "EOpImageSampleFootprintNV";
|
||||
case EOpImageSampleFootprintClampNV: return "EOpImageSampleFootprintClampNV";
|
||||
case EOpImageSampleFootprintLodNV: return "EOpImageSampleFootprintLodNV";
|
||||
case EOpImageSampleFootprintGradNV: return "EOpImageSampleFootprintGradNV";
|
||||
case EOpImageSampleFootprintGradClampNV: return "EOpImageSampleFootprintGradClampNV";
|
||||
case EOpImageFootprintGuardEnd: return "EOpImageFootprintGuardEnd";
|
||||
case EOpSamplingGuardEnd: return "EOpSamplingGuardEnd";
|
||||
case EOpTextureGuardEnd: return "EOpTextureGuardEnd";
|
||||
case EOpAddCarry: return "EOpAddCarry";
|
||||
case EOpSubBorrow: return "EOpSubBorrow";
|
||||
case EOpUMulExtended: return "EOpUMulExtended";
|
||||
case EOpIMulExtended: return "EOpIMulExtended";
|
||||
case EOpBitfieldExtract: return "EOpBitfieldExtract";
|
||||
case EOpBitfieldInsert: return "EOpBitfieldInsert";
|
||||
case EOpBitFieldReverse: return "EOpBitFieldReverse";
|
||||
case EOpBitCount: return "EOpBitCount";
|
||||
case EOpFindLSB: return "EOpFindLSB";
|
||||
case EOpFindMSB: return "EOpFindMSB";
|
||||
case EOpCountLeadingZeros: return "EOpCountLeadingZeros";
|
||||
case EOpCountTrailingZeros: return "EOpCountTrailingZeros";
|
||||
case EOpAbsDifference: return "EOpAbsDifference";
|
||||
case EOpAddSaturate: return "EOpAddSaturate";
|
||||
case EOpSubSaturate: return "EOpSubSaturate";
|
||||
case EOpAverage: return "EOpAverage";
|
||||
case EOpAverageRounded: return "EOpAverageRounded";
|
||||
case EOpMul32x16: return "EOpMul32x16";
|
||||
case EOpTraceNV: return "EOpTraceNV";
|
||||
case EOpTraceRayMotionNV: return "EOpTraceRayMotionNV";
|
||||
case EOpTraceKHR: return "EOpTraceKHR";
|
||||
case EOpReportIntersection: return "EOpReportIntersection";
|
||||
case EOpIgnoreIntersectionNV: return "EOpIgnoreIntersectionNV";
|
||||
case EOpTerminateRayNV: return "EOpTerminateRayNV";
|
||||
case EOpExecuteCallableNV: return "EOpExecuteCallableNV";
|
||||
case EOpExecuteCallableKHR: return "EOpExecuteCallableKHR";
|
||||
case EOpWritePackedPrimitiveIndices4x8NV: return "EOpWritePackedPrimitiveIndices4x8NV";
|
||||
case EOpEmitMeshTasksEXT: return "EOpEmitMeshTasksEXT";
|
||||
case EOpSetMeshOutputsEXT: return "EOpSetMeshOutputsEXT";
|
||||
case EOpRayQueryInitialize: return "EOpRayQueryInitialize";
|
||||
case EOpRayQueryTerminate: return "EOpRayQueryTerminate";
|
||||
case EOpRayQueryGenerateIntersection: return "EOpRayQueryGenerateIntersection";
|
||||
case EOpRayQueryConfirmIntersection: return "EOpRayQueryConfirmIntersection";
|
||||
case EOpRayQueryProceed: return "EOpRayQueryProceed";
|
||||
case EOpRayQueryGetIntersectionType: return "EOpRayQueryGetIntersectionType";
|
||||
case EOpRayQueryGetRayTMin: return "EOpRayQueryGetRayTMin";
|
||||
case EOpRayQueryGetRayFlags: return "EOpRayQueryGetRayFlags";
|
||||
case EOpRayQueryGetIntersectionT: return "EOpRayQueryGetIntersectionT";
|
||||
case EOpRayQueryGetIntersectionInstanceCustomIndex: return "EOpRayQueryGetIntersectionInstanceCustomIndex";
|
||||
case EOpRayQueryGetIntersectionInstanceId: return "EOpRayQueryGetIntersectionInstanceId";
|
||||
case EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset: return "EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset";
|
||||
case EOpRayQueryGetIntersectionGeometryIndex: return "EOpRayQueryGetIntersectionGeometryIndex";
|
||||
case EOpRayQueryGetIntersectionPrimitiveIndex: return "EOpRayQueryGetIntersectionPrimitiveIndex";
|
||||
case EOpRayQueryGetIntersectionBarycentrics: return "EOpRayQueryGetIntersectionBarycentrics";
|
||||
case EOpRayQueryGetIntersectionFrontFace: return "EOpRayQueryGetIntersectionFrontFace";
|
||||
case EOpRayQueryGetIntersectionCandidateAABBOpaque: return "EOpRayQueryGetIntersectionCandidateAABBOpaque";
|
||||
case EOpRayQueryGetIntersectionObjectRayDirection: return "EOpRayQueryGetIntersectionObjectRayDirection";
|
||||
case EOpRayQueryGetIntersectionObjectRayOrigin: return "EOpRayQueryGetIntersectionObjectRayOrigin";
|
||||
case EOpRayQueryGetWorldRayDirection: return "EOpRayQueryGetWorldRayDirection";
|
||||
case EOpRayQueryGetWorldRayOrigin: return "EOpRayQueryGetWorldRayOrigin";
|
||||
case EOpRayQueryGetIntersectionObjectToWorld: return "EOpRayQueryGetIntersectionObjectToWorld";
|
||||
case EOpRayQueryGetIntersectionWorldToObject: return "EOpRayQueryGetIntersectionWorldToObject";
|
||||
case EOpHitObjectTraceRayNV: return "EOpHitObjectTraceRayNV";
|
||||
case EOpHitObjectTraceRayMotionNV: return "EOpHitObjectTraceRayMotionNV";
|
||||
case EOpHitObjectRecordHitNV: return "EOpHitObjectRecordHitNV";
|
||||
case EOpHitObjectRecordHitMotionNV: return "EOpHitObjectRecordHitMotionNV";
|
||||
case EOpHitObjectRecordHitWithIndexNV: return "EOpHitObjectRecordHitWithIndexNV";
|
||||
case EOpHitObjectRecordHitWithIndexMotionNV: return "EOpHitObjectRecordHitWithIndexMotionNV";
|
||||
case EOpHitObjectRecordMissNV: return "EOpHitObjectRecordMissNV";
|
||||
case EOpHitObjectRecordMissMotionNV: return "EOpHitObjectRecordMissMotionNV";
|
||||
case EOpHitObjectRecordEmptyNV: return "EOpHitObjectRecordEmptyNV";
|
||||
case EOpHitObjectExecuteShaderNV: return "EOpHitObjectExecuteShaderNV";
|
||||
case EOpHitObjectIsEmptyNV: return "EOpHitObjectIsEmptyNV";
|
||||
case EOpHitObjectIsMissNV: return "EOpHitObjectIsMissNV";
|
||||
case EOpHitObjectIsHitNV: return "EOpHitObjectIsHitNV";
|
||||
case EOpHitObjectGetRayTMinNV: return "EOpHitObjectGetRayTMinNV";
|
||||
case EOpHitObjectGetRayTMaxNV: return "EOpHitObjectGetRayTMaxNV";
|
||||
case EOpHitObjectGetObjectRayOriginNV: return "EOpHitObjectGetObjectRayOriginNV";
|
||||
case EOpHitObjectGetObjectRayDirectionNV: return "EOpHitObjectGetObjectRayDirectionNV";
|
||||
case EOpHitObjectGetWorldRayOriginNV: return "EOpHitObjectGetWorldRayOriginNV";
|
||||
case EOpHitObjectGetWorldRayDirectionNV: return "EOpHitObjectGetWorldRayDirectionNV";
|
||||
case EOpHitObjectGetWorldToObjectNV: return "EOpHitObjectGetWorldToObjectNV";
|
||||
case EOpHitObjectGetObjectToWorldNV: return "EOpHitObjectGetObjectToWorldNV";
|
||||
case EOpHitObjectGetInstanceCustomIndexNV: return "EOpHitObjectGetInstanceCustomIndexNV";
|
||||
case EOpHitObjectGetInstanceIdNV: return "EOpHitObjectGetInstanceIdNV";
|
||||
case EOpHitObjectGetGeometryIndexNV: return "EOpHitObjectGetGeometryIndexNV";
|
||||
case EOpHitObjectGetPrimitiveIndexNV: return "EOpHitObjectGetPrimitiveIndexNV";
|
||||
case EOpHitObjectGetHitKindNV: return "EOpHitObjectGetHitKindNV";
|
||||
case EOpHitObjectGetShaderBindingTableRecordIndexNV: return "EOpHitObjectGetShaderBindingTableRecordIndexNV";
|
||||
case EOpHitObjectGetShaderRecordBufferHandleNV: return "EOpHitObjectGetShaderRecordBufferHandleNV";
|
||||
case EOpHitObjectGetAttributesNV: return "EOpHitObjectGetAttributesNV";
|
||||
case EOpHitObjectGetCurrentTimeNV: return "EOpHitObjectGetCurrentTimeNV";
|
||||
case EOpReorderThreadNV: return "EOpReorderThreadNV";
|
||||
case EOpFetchMicroTriangleVertexPositionNV: return "EOpFetchMicroTriangleVertexPositionNV";
|
||||
case EOpFetchMicroTriangleVertexBarycentricNV: return "EOpFetchMicroTriangleVertexBarycentricNV";
|
||||
case EOpClip: return "EOpClip";
|
||||
case EOpIsFinite: return "EOpIsFinite";
|
||||
case EOpLog10: return "EOpLog10";
|
||||
case EOpRcp: return "EOpRcp";
|
||||
case EOpSaturate: return "EOpSaturate";
|
||||
case EOpSinCos: return "EOpSinCos";
|
||||
case EOpGenMul: return "EOpGenMul";
|
||||
case EOpDst: return "EOpDst";
|
||||
case EOpInterlockedAdd: return "EOpInterlockedAdd";
|
||||
case EOpInterlockedAnd: return "EOpInterlockedAnd";
|
||||
case EOpInterlockedCompareExchange: return "EOpInterlockedCompareExchange";
|
||||
case EOpInterlockedCompareStore: return "EOpInterlockedCompareStore";
|
||||
case EOpInterlockedExchange: return "EOpInterlockedExchange";
|
||||
case EOpInterlockedMax: return "EOpInterlockedMax";
|
||||
case EOpInterlockedMin: return "EOpInterlockedMin";
|
||||
case EOpInterlockedOr: return "EOpInterlockedOr";
|
||||
case EOpInterlockedXor: return "EOpInterlockedXor";
|
||||
case EOpAllMemoryBarrierWithGroupSync: return "EOpAllMemoryBarrierWithGroupSync";
|
||||
case EOpDeviceMemoryBarrier: return "EOpDeviceMemoryBarrier";
|
||||
case EOpDeviceMemoryBarrierWithGroupSync: return "EOpDeviceMemoryBarrierWithGroupSync";
|
||||
case EOpWorkgroupMemoryBarrier: return "EOpWorkgroupMemoryBarrier";
|
||||
case EOpWorkgroupMemoryBarrierWithGroupSync: return "EOpWorkgroupMemoryBarrierWithGroupSync";
|
||||
case EOpEvaluateAttributeSnapped: return "EOpEvaluateAttributeSnapped";
|
||||
case EOpF32tof16: return "EOpF32tof16";
|
||||
case EOpF16tof32: return "EOpF16tof32";
|
||||
case EOpLit: return "EOpLit";
|
||||
case EOpTextureBias: return "EOpTextureBias";
|
||||
case EOpAsDouble: return "EOpAsDouble";
|
||||
case EOpD3DCOLORtoUBYTE4: return "EOpD3DCOLORtoUBYTE4";
|
||||
case EOpMethodSample: return "EOpMethodSample";
|
||||
case EOpMethodSampleBias: return "EOpMethodSampleBias";
|
||||
case EOpMethodSampleCmp: return "EOpMethodSampleCmp";
|
||||
case EOpMethodSampleCmpLevelZero: return "EOpMethodSampleCmpLevelZero";
|
||||
case EOpMethodSampleGrad: return "EOpMethodSampleGrad";
|
||||
case EOpMethodSampleLevel: return "EOpMethodSampleLevel";
|
||||
case EOpMethodLoad: return "EOpMethodLoad";
|
||||
case EOpMethodGetDimensions: return "EOpMethodGetDimensions";
|
||||
case EOpMethodGetSamplePosition: return "EOpMethodGetSamplePosition";
|
||||
case EOpMethodGather: return "EOpMethodGather";
|
||||
case EOpMethodCalculateLevelOfDetail: return "EOpMethodCalculateLevelOfDetail";
|
||||
case EOpMethodCalculateLevelOfDetailUnclamped: return "EOpMethodCalculateLevelOfDetailUnclamped";
|
||||
case EOpMethodLoad2: return "EOpMethodLoad2";
|
||||
case EOpMethodLoad3: return "EOpMethodLoad3";
|
||||
case EOpMethodLoad4: return "EOpMethodLoad4";
|
||||
case EOpMethodStore: return "EOpMethodStore";
|
||||
case EOpMethodStore2: return "EOpMethodStore2";
|
||||
case EOpMethodStore3: return "EOpMethodStore3";
|
||||
case EOpMethodStore4: return "EOpMethodStore4";
|
||||
case EOpMethodIncrementCounter: return "EOpMethodIncrementCounter";
|
||||
case EOpMethodDecrementCounter: return "EOpMethodDecrementCounter";
|
||||
case EOpMethodConsume: return "EOpMethodConsume";
|
||||
case EOpMethodGatherRed: return "EOpMethodGatherRed";
|
||||
case EOpMethodGatherGreen: return "EOpMethodGatherGreen";
|
||||
case EOpMethodGatherBlue: return "EOpMethodGatherBlue";
|
||||
case EOpMethodGatherAlpha: return "EOpMethodGatherAlpha";
|
||||
case EOpMethodGatherCmp: return "EOpMethodGatherCmp";
|
||||
case EOpMethodGatherCmpRed: return "EOpMethodGatherCmpRed";
|
||||
case EOpMethodGatherCmpGreen: return "EOpMethodGatherCmpGreen";
|
||||
case EOpMethodGatherCmpBlue: return "EOpMethodGatherCmpBlue";
|
||||
case EOpMethodGatherCmpAlpha: return "EOpMethodGatherCmpAlpha";
|
||||
case EOpMethodAppend: return "EOpMethodAppend";
|
||||
case EOpMethodRestartStrip: return "EOpMethodRestartStrip";
|
||||
case EOpMatrixSwizzle: return "EOpMatrixSwizzle";
|
||||
case EOpWaveGetLaneCount: return "EOpWaveGetLaneCount";
|
||||
case EOpWaveGetLaneIndex: return "EOpWaveGetLaneIndex";
|
||||
case EOpWaveActiveCountBits: return "EOpWaveActiveCountBits";
|
||||
case EOpWavePrefixCountBits: return "EOpWavePrefixCountBits";
|
||||
case EOpReadClockSubgroupKHR: return "EOpReadClockSubgroupKHR";
|
||||
case EOpReadClockDeviceKHR: return "EOpReadClockDeviceKHR";
|
||||
case EOpRayQueryGetIntersectionTriangleVertexPositionsEXT: return "EOpRayQueryGetIntersectionTriangleVertexPositionsEXT";
|
||||
case EOpStencilAttachmentReadEXT: return "EOpStencilAttachmentReadEXT";
|
||||
case EOpDepthAttachmentReadEXT: return "EOpDepthAttachmentReadEXT";
|
||||
case EOpImageSampleWeightedQCOM: return "EOpImageSampleWeightedQCOM";
|
||||
case EOpImageBoxFilterQCOM: return "EOpImageBoxFilterQCOM";
|
||||
case EOpImageBlockMatchSADQCOM: return "EOpImageBlockMatchSADQCOM";
|
||||
case EOpImageBlockMatchSSDQCOM: return "EOpImageBlockMatchSSDQCOM";
|
||||
}
|
||||
}
|
||||
|
||||
std::string glslangNodeToString(const TIntermNode* node) {
|
||||
if (auto nodeAsOperator = node->getAsOperator()) {
|
||||
std::string result;
|
||||
if (node->getAsAggregate()) {
|
||||
result = "Aggregate(";
|
||||
} else if (node->getAsUnaryNode()) {
|
||||
result = "Unary(";
|
||||
} else if (node->getAsBinaryNode()) {
|
||||
result = "Binary(";
|
||||
} else {
|
||||
result = "Operator(";
|
||||
}
|
||||
result += glslangOperatorToString(nodeAsOperator->getOp());
|
||||
result += ')';
|
||||
return result;
|
||||
}
|
||||
if (node->getAsLoopNode()) {
|
||||
return "Loop";
|
||||
}
|
||||
if (auto nodeAsBranch = node->getAsBranchNode()) {
|
||||
return std::string("Branch(") + glslangOperatorToString(nodeAsBranch->getFlowOp()) + ")";
|
||||
}
|
||||
if (auto nodeAsSymbol = node->getAsSymbolNode()) {
|
||||
return std::string("Symbol(") + std::string(nodeAsSymbol->getAccessName()) + ")";
|
||||
}
|
||||
if (node->getAsMethodNode()) {
|
||||
return "Method";
|
||||
}
|
||||
if (node->getAsSwitchNode()) {
|
||||
return "Switch";
|
||||
}
|
||||
if (node->getAsSelectionNode()) {
|
||||
return "Selection";
|
||||
}
|
||||
if (auto nodeAsConstantUnion = node->getAsConstantUnion()) {
|
||||
return "ConstantUnion(size = "
|
||||
+ std::to_string(nodeAsConstantUnion->getConstArray().size())
|
||||
+ ", type = "
|
||||
+ std::string(nodeAsConstantUnion->getType().getCompleteString())
|
||||
+ ")";
|
||||
}
|
||||
if (node->getAsTyped()) {
|
||||
return "Typed";
|
||||
}
|
||||
return "Node";
|
||||
}
|
||||
|
||||
std::string glslangLocToString(const glslang::TSourceLoc& loc) {
|
||||
return loc.getStringNameOrNum() + ":" + std::to_string(loc.line) + ":" + std::to_string(loc.column);
|
||||
}
|
||||
|
||||
std::string glslangNodeToStringWithLoc(const TIntermNode* node) {
|
||||
return glslangLocToString(node->getLoc()) + ":" + glslangNodeToString(node);
|
||||
}
|
||||
|
||||
} // namespace astrict
|
||||
1611
libs/astrict/src/FromGlsl.cpp
Normal file
1611
libs/astrict/src/FromGlsl.cpp
Normal file
File diff suppressed because it is too large
Load Diff
768
libs/astrict/src/ToGlsl.cpp
Normal file
768
libs/astrict/src/ToGlsl.cpp
Normal file
@@ -0,0 +1,768 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <astrict/ToGlsl.h>
|
||||
|
||||
#include <astrict/CommonTypes.h>
|
||||
#include <astrict/DebugCommon.h>
|
||||
#include <astrict/GlslTypes.h>
|
||||
#include <sstream>
|
||||
#include <unordered_set>
|
||||
#include <utils/Panic.h>
|
||||
|
||||
namespace astrict {
|
||||
|
||||
constexpr auto kIndentAmount = " ";
|
||||
constexpr auto kSpace = " ";
|
||||
constexpr auto kNewline = "\n";
|
||||
|
||||
template<typename T>
|
||||
void dumpVariableOrExpression(
|
||||
const PackFromGlsl& pack, const Function& function,
|
||||
T valueId, bool parenthesize, std::ostringstream& out);
|
||||
void dumpAnyVariableOrExpression(
|
||||
const PackFromGlsl& pack, const Function& function,
|
||||
VariableOrExpressionId valueId, bool parenthesize, std::ostringstream& out);
|
||||
|
||||
template<typename T>
|
||||
void dumpExpression(
|
||||
const PackFromGlsl& pack, const Function& function,
|
||||
const T& value, bool parenthesize, std::ostringstream& out);
|
||||
|
||||
template<typename T>
|
||||
void dumpExpressionOperandExpression(
|
||||
const PackFromGlsl& pack, const Function& function,
|
||||
const T& op, const std::vector<VariableOrExpressionId>& args,
|
||||
bool parenthesize, std::ostringstream& out);
|
||||
|
||||
template<typename T>
|
||||
void dumpStatement(
|
||||
const PackFromGlsl& pack, const Function& function, StatementBlockId blockId,
|
||||
const T& statement, int depth,
|
||||
std::ostringstream& out);
|
||||
|
||||
void dumpBlock(
|
||||
const PackFromGlsl& pack, const Function& function, StatementBlockId blockId,
|
||||
int depth, std::ostringstream& out);
|
||||
|
||||
void indent(int depth, std::ostringstream& out) {
|
||||
for (int i = 0; i < depth; ++i) {
|
||||
out << kIndentAmount;
|
||||
}
|
||||
}
|
||||
|
||||
void dumpString(const PackFromGlsl& pack, StringId stringId,
|
||||
std::ostringstream& out) {
|
||||
ASSERT_PRECONDITION(pack.strings.find(stringId) != pack.strings.end(),
|
||||
"Missing string");
|
||||
const auto& string = pack.strings.at(stringId);
|
||||
out << string;
|
||||
}
|
||||
|
||||
void dumpFunctionName(const PackFromGlsl& pack, FunctionId functionId,
|
||||
std::ostringstream& out) {
|
||||
auto name = pack.functionNames.at(functionId);
|
||||
auto indexParenthesis = name.find('(');
|
||||
out << name.substr(0, indexParenthesis);
|
||||
}
|
||||
|
||||
void dumpType(const PackFromGlsl& pack, TypeId typeId, std::ostringstream& out) {
|
||||
ASSERT_PRECONDITION(pack.types.find(typeId) != pack.types.end(),
|
||||
"Missing type definition");
|
||||
auto& type = pack.types.at(typeId);
|
||||
if (type.qualifiers) {
|
||||
dumpString(pack, type.qualifiers.value(), out);
|
||||
}
|
||||
std::visit([&](auto&& name) {
|
||||
using T = std::decay_t<decltype(name)>;
|
||||
if constexpr (std::is_same_v<T, StringId>) {
|
||||
dumpString(pack, name, out);
|
||||
} else if constexpr (std::is_same_v<T, StructId>) {
|
||||
ASSERT_PRECONDITION(pack.structs.find(name) != pack.structs.end(),
|
||||
"Missing struct definition");
|
||||
auto& strukt = pack.structs.at(name);
|
||||
dumpString(pack, strukt.name, out);
|
||||
} else {
|
||||
static_assert(always_false_v<T>, "unreachable");
|
||||
}
|
||||
}, type.name);
|
||||
for (const auto& arraySize : type.arraySizes) {
|
||||
out << "[" << arraySize << "]";
|
||||
}
|
||||
}
|
||||
|
||||
void dumpBinaryExpressionOperator(
|
||||
const PackFromGlsl& pack, const Function& function,
|
||||
ExpressionOperator op, const std::vector<VariableOrExpressionId>& args,
|
||||
const char* opString,
|
||||
std::ostringstream& out) {
|
||||
ASSERT_PRECONDITION(args.size() == 2,
|
||||
"%s must be a binary operator", rValueOperatorToString(op));
|
||||
dumpAnyVariableOrExpression(pack, function, args[0], /*parenthesize=*/true, out);
|
||||
out << kSpace << opString << kSpace;
|
||||
dumpAnyVariableOrExpression(pack, function, args[1], /*parenthesize=*/true, out);
|
||||
}
|
||||
|
||||
template<>
|
||||
void dumpExpressionOperandExpression<ExpressionOperator>(
|
||||
const PackFromGlsl& pack, const Function& function,
|
||||
const ExpressionOperator& op, const std::vector<VariableOrExpressionId>& args,
|
||||
bool parenthesize, std::ostringstream& out) {
|
||||
const char* lParen = parenthesize ? "(" : "";
|
||||
const char* rParen = parenthesize ? ")" : "";
|
||||
switch (op) {
|
||||
// Unary
|
||||
case ExpressionOperator::Negative:
|
||||
ASSERT_PRECONDITION(args.size() == 1,
|
||||
"Negative must be a unary operator");
|
||||
out << "-";
|
||||
dumpAnyVariableOrExpression(pack, function, args[0], /*parenthesize=*/true, out);
|
||||
break;
|
||||
case ExpressionOperator::LogicalNot:
|
||||
ASSERT_PRECONDITION(args.size() == 1,
|
||||
"LogicalNot must be a unary operator");
|
||||
out << "!";
|
||||
dumpAnyVariableOrExpression(pack, function, args[0], /*parenthesize=*/true, out);
|
||||
break;
|
||||
case ExpressionOperator::BitwiseNot:
|
||||
ASSERT_PRECONDITION(args.size() == 1,
|
||||
"BitwiseNot must be a unary operator");
|
||||
out << "~";
|
||||
dumpAnyVariableOrExpression(pack, function, args[0], /*parenthesize=*/true, out);
|
||||
break;
|
||||
case ExpressionOperator::PostIncrement:
|
||||
ASSERT_PRECONDITION(args.size() == 1,
|
||||
"PostIncrement must be a unary operator");
|
||||
dumpAnyVariableOrExpression(pack, function, args[0], /*parenthesize=*/true, out);
|
||||
out << "++";
|
||||
break;
|
||||
case ExpressionOperator::PostDecrement:
|
||||
ASSERT_PRECONDITION(args.size() == 1,
|
||||
"PostDecrement must be a unary operator");
|
||||
dumpAnyVariableOrExpression(pack, function, args[0], /*parenthesize=*/true, out);
|
||||
out << "--";
|
||||
break;
|
||||
case ExpressionOperator::PreIncrement:
|
||||
ASSERT_PRECONDITION(args.size() == 1,
|
||||
"PreIncrement must be a unary operator");
|
||||
out << "++";
|
||||
dumpAnyVariableOrExpression(pack, function, args[0], /*parenthesize=*/true, out);
|
||||
break;
|
||||
case ExpressionOperator::PreDecrement:
|
||||
ASSERT_PRECONDITION(args.size() == 1,
|
||||
"PreDecrement must be a unary operator");
|
||||
out << "--";
|
||||
dumpAnyVariableOrExpression(pack, function, args[0], /*parenthesize=*/true, out);
|
||||
break;
|
||||
case ExpressionOperator::ArrayLength:
|
||||
ASSERT_PRECONDITION(args.size() == 1,
|
||||
"ArrayLength must be a unary operator");
|
||||
dumpAnyVariableOrExpression(pack, function, args[0], /*parenthesize=*/true, out);
|
||||
out << ".length";
|
||||
break;
|
||||
|
||||
// Binary
|
||||
case ExpressionOperator::Add:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "+", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::Sub:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "-", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::Mul:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "*", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::Div:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "/", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::Mod:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "%", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::RightShift:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, ">>", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::LeftShift:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "<<", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::And:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "&", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::InclusiveOr:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "|", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::ExclusiveOr:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "^", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::Equal:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "==", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::NotEqual:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "!=", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::LessThan:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "<", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::GreaterThan:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, ">", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::LessThanEqual:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "<=", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::GreaterThanEqual:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, ">=", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::LogicalOr:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "||", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::LogicalXor:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "^^", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::LogicalAnd:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "&&", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::Index:
|
||||
ASSERT_PRECONDITION(args.size() == 2,
|
||||
"%s must be a binary operator", rValueOperatorToString(op));
|
||||
dumpAnyVariableOrExpression(pack, function, args[0], /*parenthesize=*/true, out);
|
||||
out << "[";
|
||||
dumpAnyVariableOrExpression(pack, function, args[1], /*parenthesize=*/true, out);
|
||||
out << "]";
|
||||
break;
|
||||
case ExpressionOperator::Assign:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "=", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::AddAssign:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "+=", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::SubAssign:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "-=", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::MulAssign:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "*=", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::DivAssign:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "/=", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::ModAssign:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "%=", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::AndAssign:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "&=", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::InclusiveOrAssign:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "|=", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::ExclusiveOrAssign:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "^=", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::LeftShiftAssign:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, "<<=", out);
|
||||
out << rParen;
|
||||
break;
|
||||
case ExpressionOperator::RightShiftAssign:
|
||||
out << lParen;
|
||||
dumpBinaryExpressionOperator(pack, function, op, args, ">>=", out);
|
||||
out << rParen;
|
||||
break;
|
||||
|
||||
// Ternary
|
||||
case ExpressionOperator::Ternary:
|
||||
ASSERT_PRECONDITION(args.size() == 3,
|
||||
"Ternary must be a ternary operator");
|
||||
out << lParen << "(";
|
||||
dumpAnyVariableOrExpression(pack, function, args[0], /*parenthesize=*/true, out);
|
||||
out << ")" << kSpace << "?" << kSpace << "(";
|
||||
dumpAnyVariableOrExpression(pack, function, args[1], /*parenthesize=*/true, out);
|
||||
out << ")" << kSpace << ":" << kSpace << "(";
|
||||
dumpAnyVariableOrExpression(pack, function, args[2], /*parenthesize=*/true, out);
|
||||
out << ")" << rParen;
|
||||
break;
|
||||
|
||||
// Variadic
|
||||
case ExpressionOperator::Comma:
|
||||
ASSERT_PRECONDITION(args.size() >= 2,
|
||||
"Comma operator must have at least two arguments");
|
||||
out << lParen;
|
||||
dumpAnyVariableOrExpression(pack, function, args[0], /*parenthesize=*/false, out);
|
||||
for (int i = 1; i < args.size(); i++) {
|
||||
out << "," << kSpace;
|
||||
dumpAnyVariableOrExpression(pack, function, args[i], /*parenthesize=*/false, out);
|
||||
}
|
||||
out << rParen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void dumpExpressionOperandExpression<FunctionId>(
|
||||
const PackFromGlsl& pack, const Function& function,
|
||||
const FunctionId& op, const std::vector<VariableOrExpressionId>& args,
|
||||
bool parenthesize, std::ostringstream& out) {
|
||||
dumpFunctionName(pack, op, out);
|
||||
out << "(";
|
||||
bool firstArg = true;
|
||||
for (auto& arg : args) {
|
||||
if (firstArg) {
|
||||
firstArg = false;
|
||||
} else {
|
||||
out << "," << kSpace;
|
||||
}
|
||||
dumpAnyVariableOrExpression(pack, function, arg, /*parenthesize=*/false, out);
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
|
||||
template <>
|
||||
void dumpExpressionOperandExpression<StructId>(
|
||||
const PackFromGlsl& pack, const Function& function,
|
||||
const StructId& op, const std::vector<VariableOrExpressionId>& args,
|
||||
bool parenthesize, std::ostringstream& out) {
|
||||
ASSERT_PRECONDITION(pack.structs.find(op) != pack.structs.end(),
|
||||
"Missing struct definition");
|
||||
auto& strukt = pack.structs.at(op);
|
||||
out << "(";
|
||||
bool firstArg = true;
|
||||
for (auto& arg : args) {
|
||||
if (firstArg) {
|
||||
firstArg = false;
|
||||
} else {
|
||||
out << "," << kSpace;
|
||||
}
|
||||
dumpAnyVariableOrExpression(pack, function, arg, /*parenthesize=*/false, out);
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
|
||||
template<>
|
||||
void dumpExpression<ExpressionOperandExpression>(
|
||||
const PackFromGlsl& pack, const Function& function,
|
||||
const ExpressionOperandExpression& value, bool parenthesize,
|
||||
std::ostringstream& out) {
|
||||
std::visit([&](auto&& op) {
|
||||
dumpExpressionOperandExpression(pack, function, op, value.args, parenthesize, out);
|
||||
}, value.op);
|
||||
}
|
||||
|
||||
template<>
|
||||
void dumpExpression<IndexStructExpression>(
|
||||
const PackFromGlsl& pack, const Function& function,
|
||||
const IndexStructExpression& value, bool parenthesize,
|
||||
std::ostringstream& out) {
|
||||
dumpAnyVariableOrExpression(pack, function, value.operand, /*parenthesize=*/true, out);
|
||||
out << ".";
|
||||
ASSERT_PRECONDITION(pack.structs.find(value.strukt) != pack.structs.end(),
|
||||
"Missing struct definition");
|
||||
auto& strukt = pack.structs.at(value.strukt);
|
||||
ASSERT_PRECONDITION(value.index < strukt.members.size(),
|
||||
"Struct member index out of bounds");
|
||||
dumpString(pack, strukt.members[value.index].name, out);
|
||||
}
|
||||
|
||||
template<>
|
||||
void dumpExpression<VectorSwizzleExpression>(
|
||||
const PackFromGlsl& pack, const Function& function,
|
||||
const VectorSwizzleExpression& value, bool parenthesize,
|
||||
std::ostringstream& out) {
|
||||
static const char COMPONENTS[] = {'x', 'y', 'z', 'w'};
|
||||
dumpAnyVariableOrExpression(pack, function, value.operand, /*parenthesize=*/true, out);
|
||||
out << ".";
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int component = (value.swizzle >> (i * 3)) & 0x7;
|
||||
if (component == 0) {
|
||||
break;
|
||||
}
|
||||
out << COMPONENTS[component - 1];
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void dumpExpression<LiteralExpression>(
|
||||
const PackFromGlsl& pack, const Function& function,
|
||||
const LiteralExpression& value, bool parenthesize,
|
||||
std::ostringstream& out) {
|
||||
std::visit([&](auto&& value) {
|
||||
out << value;
|
||||
}, value.value);
|
||||
}
|
||||
|
||||
template<>
|
||||
void dumpVariableOrExpression<ExpressionId>(
|
||||
const PackFromGlsl& pack, const Function& function, ExpressionId valueId,
|
||||
bool parenthesize, std::ostringstream& out) {
|
||||
if (*valueId == 0) {
|
||||
out << "INVALID_EXPRESSION";
|
||||
return;
|
||||
}
|
||||
ASSERT_PRECONDITION(pack.expressions.find(valueId) != pack.expressions.end(),
|
||||
"Missing Expression");
|
||||
std::visit([&](auto&& value) {
|
||||
dumpExpression(pack, function, value, parenthesize, out);
|
||||
}, pack.expressions.at(valueId));
|
||||
}
|
||||
|
||||
template<>
|
||||
void dumpVariableOrExpression<GlobalVariableId>(
|
||||
const PackFromGlsl& pack, const Function& function, GlobalVariableId valueId,
|
||||
bool parenthesize, std::ostringstream& out) {
|
||||
if (*valueId == 0) {
|
||||
out << "INVALID_GLOBAL_SYMBOL";
|
||||
return;
|
||||
}
|
||||
ASSERT_PRECONDITION(pack.globalVariables.find(valueId) != pack.globalVariables.end(),
|
||||
"Missing global symbol");
|
||||
|
||||
auto globalSymbol = pack.globalVariables.at(valueId);
|
||||
dumpString(pack, globalSymbol.name, out);
|
||||
}
|
||||
|
||||
template<>
|
||||
void dumpVariableOrExpression<LocalVariableId>(
|
||||
const PackFromGlsl& pack, const Function& function, LocalVariableId valueId,
|
||||
bool parenthesize, std::ostringstream& out) {
|
||||
if (*valueId == 0) {
|
||||
out << "INVALID_LOCAL_SYMBOL";
|
||||
return;
|
||||
}
|
||||
ASSERT_PRECONDITION(function.localVariables.find(valueId) != function.localVariables.end(),
|
||||
"Missing local symbol");
|
||||
|
||||
auto& localSymbol = function.localVariables.at(valueId);
|
||||
dumpString(pack, localSymbol.name, out);
|
||||
}
|
||||
|
||||
template<>
|
||||
void dumpStatement<ExpressionId>(
|
||||
const PackFromGlsl& pack, const Function& function, StatementBlockId blockId,
|
||||
const ExpressionId& statement, int depth,
|
||||
std::ostringstream& out) {
|
||||
indent(depth, out);
|
||||
dumpAnyVariableOrExpression(pack, function, statement, /*parenthesize=*/false, out);
|
||||
out << ";" << kNewline;
|
||||
}
|
||||
|
||||
template<>
|
||||
void dumpStatement<IfStatement>(
|
||||
const PackFromGlsl& pack, const Function& function, StatementBlockId blockId,
|
||||
const IfStatement& statement, int depth,
|
||||
std::ostringstream& out) {
|
||||
indent(depth, out);
|
||||
out << "if" << kSpace << "(";
|
||||
dumpAnyVariableOrExpression(pack, function, statement.condition, /*parenthesize=*/false, out);
|
||||
out << ")" << kSpace << "{" << kNewline;
|
||||
dumpBlock(pack, function, statement.thenBlock, depth + 1, out);
|
||||
if (statement.elseBlock) {
|
||||
indent(depth, out);
|
||||
out << "}" << kSpace << "else" << kSpace << "{" << kNewline;
|
||||
dumpBlock(pack, function, statement.elseBlock.value(), depth + 1, out);
|
||||
}
|
||||
indent(depth, out);
|
||||
out << "}" << kNewline;
|
||||
}
|
||||
|
||||
template<>
|
||||
void dumpStatement<SwitchStatement>(
|
||||
const PackFromGlsl& pack, const Function& function, StatementBlockId blockId,
|
||||
const SwitchStatement& statement, int depth,
|
||||
std::ostringstream& out) {
|
||||
indent(depth, out);
|
||||
out << "switch" << kSpace << "(";
|
||||
dumpAnyVariableOrExpression(pack, function, statement.condition, /*parenthesize=*/false, out);
|
||||
out << ")" << kSpace << "{" << kNewline;
|
||||
dumpBlock(pack, function, statement.body, depth + 1, out);
|
||||
indent(depth, out);
|
||||
out << "}" << kNewline;
|
||||
}
|
||||
|
||||
template<>
|
||||
void dumpStatement<BranchStatement>(
|
||||
const PackFromGlsl& pack, const Function& function, StatementBlockId blockId,
|
||||
const BranchStatement& statement, int depth,
|
||||
std::ostringstream& out) {
|
||||
switch (statement.op) {
|
||||
case BranchOperator::Discard:
|
||||
indent(depth, out);
|
||||
out << "discard";
|
||||
break;
|
||||
case BranchOperator::TerminateInvocation:
|
||||
indent(depth, out);
|
||||
out << "terminateInvocation";
|
||||
break;
|
||||
case BranchOperator::Demote:
|
||||
indent(depth, out);
|
||||
out << "demote";
|
||||
break;
|
||||
case BranchOperator::TerminateRayEXT:
|
||||
indent(depth, out);
|
||||
out << "terminateRayEXT";
|
||||
break;
|
||||
case BranchOperator::IgnoreIntersectionEXT:
|
||||
indent(depth, out);
|
||||
out << "terminateIntersectionEXT";
|
||||
break;
|
||||
case BranchOperator::Return:
|
||||
indent(depth, out);
|
||||
out << "return";
|
||||
break;
|
||||
case BranchOperator::Break:
|
||||
indent(depth, out);
|
||||
out << "break";
|
||||
break;
|
||||
case BranchOperator::Continue:
|
||||
indent(depth, out);
|
||||
out << "continue";
|
||||
break;
|
||||
case BranchOperator::Case:
|
||||
indent(depth - 1, out);
|
||||
out << "case";
|
||||
break;
|
||||
case BranchOperator::Default:
|
||||
indent(depth - 1, out);
|
||||
out << "default";
|
||||
break;
|
||||
}
|
||||
if (statement.operand) {
|
||||
out << " ";
|
||||
dumpAnyVariableOrExpression(pack, function, statement.operand.value(),
|
||||
/*parenthesize=*/false, out);
|
||||
}
|
||||
switch (statement.op) {
|
||||
case BranchOperator::Case:
|
||||
case BranchOperator::Default:
|
||||
out << ":" << kNewline;
|
||||
break;
|
||||
default:
|
||||
out << ";" << kNewline;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void dumpStatement<LoopStatement>(
|
||||
const PackFromGlsl& pack, const Function& function, StatementBlockId blockId,
|
||||
const LoopStatement& statement, int depth,
|
||||
std::ostringstream& out) {
|
||||
if (statement.testFirst) {
|
||||
if (statement.terminal) {
|
||||
indent(depth, out);
|
||||
out << "for" << kSpace << "(;" << kSpace;
|
||||
dumpAnyVariableOrExpression(pack, function, statement.condition,
|
||||
/*parenthesize=*/false, out);
|
||||
out << ";" << kSpace;
|
||||
dumpAnyVariableOrExpression(pack, function, statement.terminal.value(),
|
||||
/*parenthesize=*/false, out);
|
||||
} else {
|
||||
indent(depth, out);
|
||||
out << "while" << kSpace << "(";
|
||||
dumpAnyVariableOrExpression(pack, function, statement.condition,
|
||||
/*parenthesize=*/false, out);
|
||||
}
|
||||
out << ")" << kSpace << "{" << kNewline;
|
||||
dumpBlock(pack, function, statement.body, depth + 1, out);
|
||||
indent(depth, out);
|
||||
out << "}" << kNewline;
|
||||
} else {
|
||||
indent(depth, out);
|
||||
out << "do" << kSpace << "{" << kNewline;
|
||||
dumpBlock(pack, function, statement.body, depth + 1, out);
|
||||
indent(depth, out);
|
||||
out << "}" << kSpace << "while" << kSpace << "(";
|
||||
dumpAnyVariableOrExpression(pack, function, statement.condition, /*parenthesize=*/false, out);
|
||||
out << ");" << kNewline;
|
||||
}
|
||||
}
|
||||
|
||||
void dumpAnyVariableOrExpression(
|
||||
const PackFromGlsl& pack, const Function& function, VariableOrExpressionId valueId,
|
||||
bool parenthesize, std::ostringstream& out) {
|
||||
std::visit([&](auto&& variantValueId){
|
||||
dumpVariableOrExpression(pack, function, variantValueId, parenthesize, out);
|
||||
}, valueId);
|
||||
}
|
||||
|
||||
void dumpBlock(
|
||||
const PackFromGlsl& pack, const Function& function, StatementBlockId blockId,
|
||||
int depth, std::ostringstream& out) {
|
||||
ASSERT_PRECONDITION(pack.statementBlocks.find(blockId) != pack.statementBlocks.end(),
|
||||
"Missing block definition");
|
||||
for (auto statement : pack.statementBlocks.at(blockId)) {
|
||||
std::visit([&](auto&& variantStatement){
|
||||
dumpStatement(pack, function, blockId, variantStatement, depth, out);
|
||||
}, statement);
|
||||
}
|
||||
}
|
||||
|
||||
void dumpSymbolDefinition(
|
||||
const PackFromGlsl& pack, const Variable& symbol,
|
||||
std::ostringstream& out) {
|
||||
ASSERT_PRECONDITION(symbol.type.has_value(),
|
||||
"Symbol definition must have type");
|
||||
dumpType(pack, symbol.type.value(), out);
|
||||
out << " "; // required space
|
||||
dumpString(pack, symbol.name, out);
|
||||
}
|
||||
|
||||
void dumpFunction(
|
||||
const PackFromGlsl& pack, const FunctionId& functionId, bool dumpBody,
|
||||
std::ostringstream& out) {
|
||||
if (!dumpBody && pack.functions.find(functionId) == pack.functions.end()) {
|
||||
// TODO: prune function prototypes with no actual definition.
|
||||
return;
|
||||
}
|
||||
ASSERT_PRECONDITION(pack.functions.find(functionId) != pack.functions.end(),
|
||||
"Missing function definition");
|
||||
auto& function = pack.functions.at(functionId);
|
||||
dumpType(pack, function.returnType, out);
|
||||
out << " ";
|
||||
dumpFunctionName(pack, function.name, out);
|
||||
out << "(";
|
||||
std::unordered_set<LocalVariableId> parameterSymbolIds;
|
||||
bool firstParameter = true;
|
||||
for (const auto& parameterId : function.parameters) {
|
||||
if (firstParameter) {
|
||||
firstParameter = false;
|
||||
} else {
|
||||
out << "," << kSpace;
|
||||
}
|
||||
parameterSymbolIds.insert(parameterId);
|
||||
const auto& parameter = function.localVariables.at(parameterId);
|
||||
dumpSymbolDefinition(pack, parameter, out);
|
||||
}
|
||||
out << ")";
|
||||
if (dumpBody) {
|
||||
out << kSpace << "{" << kNewline;
|
||||
for (const auto& localSymbol : function.localVariables) {
|
||||
if (parameterSymbolIds.find(localSymbol.first) == parameterSymbolIds.end()) {
|
||||
out << kIndentAmount;
|
||||
dumpSymbolDefinition(pack, localSymbol.second, out);
|
||||
out << ";" << kNewline;
|
||||
}
|
||||
}
|
||||
dumpBlock(pack, function, function.body, 1, out);
|
||||
out << "}" << kNewline;
|
||||
} else {
|
||||
out << ";" << kNewline;
|
||||
}
|
||||
}
|
||||
|
||||
void dumpStruct(const PackFromGlsl& pack, StructId structId, std::ostringstream& out) {
|
||||
ASSERT_PRECONDITION(pack.structs.find(structId) != pack.structs.end(),
|
||||
"Missing struct definition");
|
||||
auto& strukt = pack.structs.at(structId);
|
||||
out << "struct ";
|
||||
dumpString(pack, strukt.name, out);
|
||||
out << kSpace << "{" << kNewline;
|
||||
for (const auto& member : strukt.members) {
|
||||
indent(1, out);
|
||||
dumpType(pack, member.type, out);
|
||||
out << " "; // non-optional
|
||||
dumpString(pack, member.name, out);
|
||||
out << ";" << kNewline;
|
||||
}
|
||||
out << "};" << kNewline;
|
||||
}
|
||||
|
||||
void toGlsl(const PackFromGlsl& pack, std::ostringstream& out) {
|
||||
const Function emptyFunction{};
|
||||
for (auto structId : pack.structsInOrder) {
|
||||
dumpStruct(pack, structId, out);
|
||||
}
|
||||
std::unordered_set<GlobalVariableId> globalSymbolIdsWithValues;
|
||||
for (auto globalSymbolPair : pack.globalSymbolsInOrder) {
|
||||
globalSymbolIdsWithValues.insert(globalSymbolPair.first);
|
||||
}
|
||||
for (auto globalSymbolPair : pack.globalVariables) {
|
||||
if (globalSymbolIdsWithValues.find(globalSymbolPair.first)
|
||||
== globalSymbolIdsWithValues.end()) {
|
||||
const auto& globalSymbol = pack.globalVariables.at(globalSymbolPair.first);
|
||||
if (globalSymbol.type) {
|
||||
dumpSymbolDefinition(pack, globalSymbol, out);
|
||||
out << ";" << kNewline;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto globalSymbolPair : pack.globalSymbolsInOrder) {
|
||||
const auto& globalSymbol = pack.globalVariables.at(globalSymbolPair.first);
|
||||
dumpSymbolDefinition(pack, globalSymbol, out);
|
||||
out << kSpace << "=" << kSpace;
|
||||
dumpAnyVariableOrExpression(pack, emptyFunction, globalSymbolPair.second,
|
||||
/*parenthesize=*/false, out);
|
||||
out << ";" << kNewline;
|
||||
}
|
||||
for (auto functionId : pack.functionPrototypes) {
|
||||
dumpFunction(pack, functionId, /*dumpBody=*/false, out);
|
||||
}
|
||||
for (auto functionId : pack.functionsInOrder) {
|
||||
dumpFunction(pack, functionId, /*dumpBody=*/true, out);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace astrict
|
||||
35
libs/astrict/tests/test_FromGlsl.cpp
Normal file
35
libs/astrict/tests/test_FromGlsl.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <astrict/FromGlsl.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace astrict;
|
||||
|
||||
TEST(Pack, Pack) {
|
||||
std::string shaderCode(R"(
|
||||
void material(inout MaterialInputs material) {
|
||||
prepareMaterial(material);
|
||||
material.baseColor = texture(materialParams_sampler, vec3(0.0, 0.0));
|
||||
}
|
||||
)");
|
||||
// auto result = std::get<std::vector<uint8_t>>(compress(shaderCode));
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -81,7 +81,7 @@ include_directories(${CMAKE_BINARY_DIR})
|
||||
add_library(${TARGET} STATIC ${HDRS} ${PRIVATE_HDRS} ${SRCS})
|
||||
target_include_directories(${TARGET} PUBLIC ${PUBLIC_HDR_DIR})
|
||||
set_target_properties(${TARGET} PROPERTIES FOLDER Libs)
|
||||
target_link_libraries(${TARGET} shaders filabridge utils smol-v)
|
||||
target_link_libraries(${TARGET} shaders filabridge utils smol-v astrict)
|
||||
|
||||
# We are being naughty and accessing private headers here
|
||||
# For spirv-tools, we're just following glslang's example
|
||||
@@ -157,4 +157,3 @@ target_include_directories(${TARGET} PRIVATE src)
|
||||
target_link_libraries(${TARGET} filamat gtest)
|
||||
|
||||
set_target_properties(${TARGET} PROPERTIES FOLDER Tests)
|
||||
|
||||
|
||||
@@ -43,6 +43,9 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <astrict/FromGlsl.h>
|
||||
#include <astrict/ToGlsl.h>
|
||||
|
||||
using namespace glslang;
|
||||
using namespace spirv_cross;
|
||||
using namespace spvtools;
|
||||
@@ -372,6 +375,11 @@ bool GLSLPostProcessor::process(const std::string& inputShader, Config const& co
|
||||
return false;
|
||||
}
|
||||
|
||||
auto pack = astrict::fromGlsl(*tShader.getIntermediate());
|
||||
std::ostringstream dump;
|
||||
astrict::toGlsl(pack, dump);
|
||||
slog.i << dump.str() << io::endl;
|
||||
|
||||
switch (mOptimization) {
|
||||
case MaterialBuilder::Optimization::NONE:
|
||||
if (internalConfig.spirvOutput) {
|
||||
|
||||
Reference in New Issue
Block a user