early-access version 1255
This commit is contained in:
1
externals/sirit/src/.gitignore
vendored
Executable file
1
externals/sirit/src/.gitignore
vendored
Executable file
@@ -0,0 +1 @@
|
||||
sirit.h
|
39
externals/sirit/src/CMakeLists.txt
vendored
Executable file
39
externals/sirit/src/CMakeLists.txt
vendored
Executable file
@@ -0,0 +1,39 @@
|
||||
add_library(sirit
|
||||
../include/sirit/sirit.h
|
||||
sirit.cpp
|
||||
op.cpp
|
||||
op.h
|
||||
stream.cpp
|
||||
stream.h
|
||||
operand.cpp
|
||||
operand.h
|
||||
literal_number.cpp
|
||||
literal_number.h
|
||||
literal_string.cpp
|
||||
literal_string.h
|
||||
common_types.h
|
||||
instructions/type.cpp
|
||||
instructions/constant.cpp
|
||||
instructions/function.cpp
|
||||
instructions/flow.cpp
|
||||
instructions/debug.cpp
|
||||
instructions/memory.cpp
|
||||
instructions/annotation.cpp
|
||||
instructions/misc.cpp
|
||||
instructions/logical.cpp
|
||||
instructions/conversion.cpp
|
||||
instructions/bit.cpp
|
||||
instructions/arithmetic.cpp
|
||||
instructions/extension.cpp
|
||||
instructions/image.cpp
|
||||
instructions/group.cpp
|
||||
instructions/barrier.cpp
|
||||
instructions/atomic.cpp
|
||||
)
|
||||
|
||||
target_compile_options(sirit PRIVATE ${SIRIT_CXX_FLAGS})
|
||||
|
||||
target_include_directories(sirit
|
||||
PUBLIC ../include
|
||||
PRIVATE . ${SPIRV-Headers_SOURCE_DIR}/include
|
||||
INTERFACE ${SPIRV-Headers_SOURCE_DIR}/include)
|
31
externals/sirit/src/common_types.h
vendored
Executable file
31
externals/sirit/src/common_types.h
vendored
Executable file
@@ -0,0 +1,31 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
using u8 = std::uint8_t;
|
||||
using u16 = std::uint16_t;
|
||||
using u32 = std::uint32_t;
|
||||
using u64 = std::uint64_t;
|
||||
using uptr = std::uintptr_t;
|
||||
|
||||
using s8 = std::int8_t;
|
||||
using s16 = std::int16_t;
|
||||
using s32 = std::int32_t;
|
||||
using s64 = std::int64_t;
|
||||
using sptr = std::intptr_t;
|
||||
|
||||
using f32 = float;
|
||||
using f64 = double;
|
||||
static_assert(sizeof(f32) == sizeof(u32), "f32 must be 32 bits wide");
|
||||
static_assert(sizeof(f64) == sizeof(u64), "f64 must be 64 bits wide");
|
||||
|
||||
} // namespace Sirit
|
35
externals/sirit/src/instructions/annotation.cpp
vendored
Executable file
35
externals/sirit/src/instructions/annotation.cpp
vendored
Executable file
@@ -0,0 +1,35 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "common_types.h"
|
||||
#include "op.h"
|
||||
#include "sirit/sirit.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
Id Module::Decorate(Id target, spv::Decoration decoration, const std::vector<Literal>& literals) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpDecorate)};
|
||||
op->Add(target);
|
||||
op->Add(static_cast<u32>(decoration));
|
||||
op->Add(literals);
|
||||
AddAnnotation(std::move(op));
|
||||
return target;
|
||||
}
|
||||
|
||||
Id Module::MemberDecorate(Id structure_type, Literal member, spv::Decoration decoration,
|
||||
const std::vector<Literal>& literals) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpMemberDecorate)};
|
||||
op->Add(structure_type);
|
||||
op->Add(member);
|
||||
op->Add(static_cast<u32>(decoration));
|
||||
op->Add(literals);
|
||||
AddAnnotation(std::move(op));
|
||||
return structure_type;
|
||||
}
|
||||
|
||||
} // namespace Sirit
|
57
externals/sirit/src/instructions/arithmetic.cpp
vendored
Executable file
57
externals/sirit/src/instructions/arithmetic.cpp
vendored
Executable file
@@ -0,0 +1,57 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include "common_types.h"
|
||||
#include "op.h"
|
||||
#include "sirit/sirit.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
#define DEFINE_UNARY(funcname, opcode) \
|
||||
Id Module::funcname(Id result_type, Id operand) { \
|
||||
auto op{std::make_unique<Op>(opcode, bound++, result_type)}; \
|
||||
op->Add(operand); \
|
||||
return AddCode(std::move(op)); \
|
||||
}
|
||||
|
||||
#define DEFINE_BINARY(funcname, opcode) \
|
||||
Id Module::funcname(Id result_type, Id operand_1, Id operand_2) { \
|
||||
auto op{std::make_unique<Op>(opcode, bound++, result_type)}; \
|
||||
op->Add(operand_1); \
|
||||
op->Add(operand_2); \
|
||||
return AddCode(std::move(op)); \
|
||||
}
|
||||
|
||||
#define DEFINE_TRINARY(funcname, opcode) \
|
||||
Id Module::funcname(Id result_type, Id operand_1, Id operand_2, Id operand_3) { \
|
||||
auto op{std::make_unique<Op>(opcode, bound++, result_type)}; \
|
||||
op->Add(operand_1); \
|
||||
op->Add(operand_2); \
|
||||
op->Add(operand_3); \
|
||||
return AddCode(std::move(op)); \
|
||||
}
|
||||
|
||||
DEFINE_UNARY(OpSNegate, spv::Op::OpSNegate)
|
||||
DEFINE_UNARY(OpFNegate, spv::Op::OpFNegate)
|
||||
|
||||
DEFINE_BINARY(OpIAdd, spv::Op::OpIAdd)
|
||||
DEFINE_BINARY(OpFAdd, spv::Op::OpFAdd)
|
||||
DEFINE_BINARY(OpISub, spv::Op::OpISub)
|
||||
DEFINE_BINARY(OpFSub, spv::Op::OpFSub)
|
||||
DEFINE_BINARY(OpIMul, spv::Op::OpIMul)
|
||||
DEFINE_BINARY(OpFMul, spv::Op::OpFMul)
|
||||
DEFINE_BINARY(OpUDiv, spv::Op::OpUDiv)
|
||||
DEFINE_BINARY(OpSDiv, spv::Op::OpSDiv)
|
||||
DEFINE_BINARY(OpFDiv, spv::Op::OpFDiv)
|
||||
DEFINE_BINARY(OpUMod, spv::Op::OpUMod)
|
||||
DEFINE_BINARY(OpSMod, spv::Op::OpSMod)
|
||||
DEFINE_BINARY(OpFMod, spv::Op::OpFMod)
|
||||
DEFINE_BINARY(OpSRem, spv::Op::OpSRem)
|
||||
DEFINE_BINARY(OpFRem, spv::Op::OpFRem)
|
||||
DEFINE_BINARY(OpIAddCarry, spv::Op::OpIAddCarry)
|
||||
|
||||
} // namespace Sirit
|
148
externals/sirit/src/instructions/atomic.cpp
vendored
Executable file
148
externals/sirit/src/instructions/atomic.cpp
vendored
Executable file
@@ -0,0 +1,148 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include "common_types.h"
|
||||
#include "op.h"
|
||||
#include "sirit/sirit.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
Id Module::OpAtomicLoad(Id result_type, Id pointer, Id memory, Id semantics) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpAtomicLoad, bound++, result_type)};
|
||||
op->Add(pointer);
|
||||
op->Add(memory);
|
||||
op->Add(semantics);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpAtomicStore(Id pointer, Id memory, Id semantics, Id value) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpAtomicStore)};
|
||||
op->Add(pointer);
|
||||
op->Add(memory);
|
||||
op->Add(semantics);
|
||||
op->Add(value);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpAtomicExchange(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpAtomicExchange, bound++, result_type)};
|
||||
op->Add(pointer);
|
||||
op->Add(memory);
|
||||
op->Add(semantics);
|
||||
op->Add(value);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpAtomicCompareExchange(Id result_type, Id pointer, Id memory, Id equal, Id unequal,
|
||||
Id value, Id comparator) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpAtomicCompareExchange, bound++, result_type)};
|
||||
op->Add(pointer);
|
||||
op->Add(memory);
|
||||
op->Add(equal);
|
||||
op->Add(unequal);
|
||||
op->Add(value);
|
||||
op->Add(comparator);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpAtomicIIncrement(Id result_type, Id pointer, Id memory, Id semantics) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpAtomicIIncrement, bound++, result_type)};
|
||||
op->Add(pointer);
|
||||
op->Add(memory);
|
||||
op->Add(semantics);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpAtomicIDecrement(Id result_type, Id pointer, Id memory, Id semantics) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpAtomicIDecrement, bound++, result_type)};
|
||||
op->Add(pointer);
|
||||
op->Add(memory);
|
||||
op->Add(semantics);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpAtomicIAdd(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpAtomicIAdd, bound++, result_type)};
|
||||
op->Add(pointer);
|
||||
op->Add(memory);
|
||||
op->Add(semantics);
|
||||
op->Add(value);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpAtomicISub(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpAtomicISub, bound++, result_type)};
|
||||
op->Add(pointer);
|
||||
op->Add(memory);
|
||||
op->Add(semantics);
|
||||
op->Add(value);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpAtomicSMin(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpAtomicSMin, bound++, result_type)};
|
||||
op->Add(pointer);
|
||||
op->Add(memory);
|
||||
op->Add(semantics);
|
||||
op->Add(value);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpAtomicUMin(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpAtomicUMin, bound++, result_type)};
|
||||
op->Add(pointer);
|
||||
op->Add(memory);
|
||||
op->Add(semantics);
|
||||
op->Add(value);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpAtomicSMax(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpAtomicSMax, bound++, result_type)};
|
||||
op->Add(pointer);
|
||||
op->Add(memory);
|
||||
op->Add(semantics);
|
||||
op->Add(value);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpAtomicUMax(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpAtomicUMax, bound++, result_type)};
|
||||
op->Add(pointer);
|
||||
op->Add(memory);
|
||||
op->Add(semantics);
|
||||
op->Add(value);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpAtomicAnd(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpAtomicAnd, bound++, result_type)};
|
||||
op->Add(pointer);
|
||||
op->Add(memory);
|
||||
op->Add(semantics);
|
||||
op->Add(value);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpAtomicOr(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpAtomicOr, bound++, result_type)};
|
||||
op->Add(pointer);
|
||||
op->Add(memory);
|
||||
op->Add(semantics);
|
||||
op->Add(value);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpAtomicXor(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpAtomicXor, bound++, result_type)};
|
||||
op->Add(pointer);
|
||||
op->Add(memory);
|
||||
op->Add(semantics);
|
||||
op->Add(value);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
} // namespace Sirit
|
28
externals/sirit/src/instructions/barrier.cpp
vendored
Executable file
28
externals/sirit/src/instructions/barrier.cpp
vendored
Executable file
@@ -0,0 +1,28 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include "op.h"
|
||||
#include "sirit/sirit.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
Id Module::OpControlBarrier(Id execution, Id memory, Id semantics) {
|
||||
auto op = std::make_unique<Op>(spv::Op::OpControlBarrier);
|
||||
op->Add(execution);
|
||||
op->Add(memory);
|
||||
op->Add(semantics);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpMemoryBarrier(Id scope, Id semantics) {
|
||||
auto op = std::make_unique<Op>(spv::Op::OpMemoryBarrier);
|
||||
op->Add(scope);
|
||||
op->Add(semantics);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
} // namespace Sirit
|
99
externals/sirit/src/instructions/bit.cpp
vendored
Executable file
99
externals/sirit/src/instructions/bit.cpp
vendored
Executable file
@@ -0,0 +1,99 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include "common_types.h"
|
||||
#include "op.h"
|
||||
#include "sirit/sirit.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
Id Module::OpShiftRightLogical(Id result_type, Id base, Id shift) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpShiftRightLogical, bound++, result_type)};
|
||||
op->Add(base);
|
||||
op->Add(shift);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpShiftRightArithmetic(Id result_type, Id base, Id shift) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpShiftRightArithmetic, bound++, result_type)};
|
||||
op->Add(base);
|
||||
op->Add(shift);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpShiftLeftLogical(Id result_type, Id base, Id shift) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpShiftLeftLogical, bound++, result_type)};
|
||||
op->Add(base);
|
||||
op->Add(shift);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpBitwiseOr(Id result_type, Id operand_1, Id operand_2) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpBitwiseOr, bound++, result_type)};
|
||||
op->Add(operand_1);
|
||||
op->Add(operand_2);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpBitwiseXor(Id result_type, Id operand_1, Id operand_2) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpBitwiseXor, bound++, result_type)};
|
||||
op->Add(operand_1);
|
||||
op->Add(operand_2);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpBitwiseAnd(Id result_type, Id operand_1, Id operand_2) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpBitwiseAnd, bound++, result_type)};
|
||||
op->Add(operand_1);
|
||||
op->Add(operand_2);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpNot(Id result_type, Id operand) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpNot, bound++, result_type)};
|
||||
op->Add(operand);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpBitFieldInsert(Id result_type, Id base, Id insert, Id offset, Id count) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpBitFieldInsert, bound++, result_type)};
|
||||
op->Add(base);
|
||||
op->Add(insert);
|
||||
op->Add(offset);
|
||||
op->Add(count);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpBitFieldSExtract(Id result_type, Id base, Id offset, Id count) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpBitFieldSExtract, bound++, result_type)};
|
||||
op->Add(base);
|
||||
op->Add(offset);
|
||||
op->Add(count);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpBitFieldUExtract(Id result_type, Id base, Id offset, Id count) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpBitFieldUExtract, bound++, result_type)};
|
||||
op->Add(base);
|
||||
op->Add(offset);
|
||||
op->Add(count);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpBitReverse(Id result_type, Id base) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpBitReverse, bound++, result_type)};
|
||||
op->Add(base);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpBitCount(Id result_type, Id base) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpBitCount, bound++, result_type)};
|
||||
op->Add(base);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
} // namespace Sirit
|
46
externals/sirit/src/instructions/constant.cpp
vendored
Executable file
46
externals/sirit/src/instructions/constant.cpp
vendored
Executable file
@@ -0,0 +1,46 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include "op.h"
|
||||
#include "sirit/sirit.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
Id Module::ConstantTrue(Id result_type) {
|
||||
return AddDeclaration(std::make_unique<Op>(spv::Op::OpConstantTrue, bound, result_type));
|
||||
}
|
||||
|
||||
Id Module::ConstantFalse(Id result_type) {
|
||||
return AddDeclaration(std::make_unique<Op>(spv::Op::OpConstantFalse, bound, result_type));
|
||||
}
|
||||
|
||||
Id Module::Constant(Id result_type, const Literal& literal) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpConstant, bound, result_type)};
|
||||
op->Add(literal);
|
||||
return AddDeclaration(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::ConstantComposite(Id result_type, const std::vector<Id>& constituents) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpConstantComposite, bound, result_type)};
|
||||
op->Add(constituents);
|
||||
return AddDeclaration(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::ConstantSampler(Id result_type, spv::SamplerAddressingMode addressing_mode,
|
||||
bool normalized, spv::SamplerFilterMode filter_mode) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpConstantSampler, bound, result_type)};
|
||||
op->Add(static_cast<u32>(addressing_mode));
|
||||
op->Add(normalized ? 1 : 0);
|
||||
op->Add(static_cast<u32>(filter_mode));
|
||||
return AddDeclaration(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::ConstantNull(Id result_type) {
|
||||
return AddDeclaration(std::make_unique<Op>(spv::Op::OpConstantNull, bound, result_type));
|
||||
}
|
||||
|
||||
} // namespace Sirit
|
31
externals/sirit/src/instructions/conversion.cpp
vendored
Executable file
31
externals/sirit/src/instructions/conversion.cpp
vendored
Executable file
@@ -0,0 +1,31 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include "common_types.h"
|
||||
#include "op.h"
|
||||
#include "sirit/sirit.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
#define DEFINE_UNARY(opcode) \
|
||||
Id Module::opcode(Id result_type, Id operand) { \
|
||||
auto op{std::make_unique<Op>(spv::Op::opcode, bound++, result_type)}; \
|
||||
op->Add(operand); \
|
||||
return AddCode(std::move(op)); \
|
||||
}
|
||||
|
||||
DEFINE_UNARY(OpConvertFToU)
|
||||
DEFINE_UNARY(OpConvertFToS)
|
||||
DEFINE_UNARY(OpConvertSToF)
|
||||
DEFINE_UNARY(OpConvertUToF)
|
||||
DEFINE_UNARY(OpUConvert)
|
||||
DEFINE_UNARY(OpSConvert)
|
||||
DEFINE_UNARY(OpFConvert)
|
||||
DEFINE_UNARY(OpQuantizeToF16)
|
||||
DEFINE_UNARY(OpBitcast)
|
||||
|
||||
} // namespace Sirit
|
47
externals/sirit/src/instructions/debug.cpp
vendored
Executable file
47
externals/sirit/src/instructions/debug.cpp
vendored
Executable file
@@ -0,0 +1,47 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "op.h"
|
||||
#include "sirit/sirit.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
Id Module::Name(Id target, std::string name) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpName)};
|
||||
op->Add(target);
|
||||
op->Add(std::move(name));
|
||||
debug.push_back(std::move(op));
|
||||
return target;
|
||||
}
|
||||
|
||||
Id Module::MemberName(Id type, u32 member, std::string name) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpMemberName)};
|
||||
op->Add(type);
|
||||
op->Add(member);
|
||||
op->Add(std::move(name));
|
||||
debug.push_back(std::move(op));
|
||||
return type;
|
||||
}
|
||||
|
||||
Id Module::String(std::string string) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpString, bound++)};
|
||||
op->Add(std::move(string));
|
||||
const auto id = op.get();
|
||||
debug.push_back(std::move(op));
|
||||
return id;
|
||||
}
|
||||
|
||||
Id Module::OpLine(Id file, Literal line, Literal column) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpLine)};
|
||||
op->Add(file);
|
||||
op->Add(line);
|
||||
op->Add(column);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
} // namespace Sirit
|
77
externals/sirit/src/instructions/extension.cpp
vendored
Executable file
77
externals/sirit/src/instructions/extension.cpp
vendored
Executable file
@@ -0,0 +1,77 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <spirv/unified1/GLSL.std.450.h>
|
||||
#include "common_types.h"
|
||||
#include "op.h"
|
||||
#include "sirit/sirit.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
Id Module::OpExtInst(Id result_type, Id set, u32 instruction, const std::vector<Id>& operands) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpExtInst, bound++, result_type)};
|
||||
op->Add(set);
|
||||
op->Add(instruction);
|
||||
op->Add(operands);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
#define DEFINE_UNARY(funcname, opcode) \
|
||||
Id Module::funcname(Id result_type, Id operand) { \
|
||||
return OpExtInst(result_type, GetGLSLstd450(), opcode, operand); \
|
||||
}
|
||||
|
||||
#define DEFINE_BINARY(funcname, opcode) \
|
||||
Id Module::funcname(Id result_type, Id operand_1, Id operand_2) { \
|
||||
return OpExtInst(result_type, GetGLSLstd450(), opcode, operand_1, operand_2); \
|
||||
}
|
||||
|
||||
#define DEFINE_TRINARY(funcname, opcode) \
|
||||
Id Module::funcname(Id result_type, Id operand_1, Id operand_2, Id operand_3) { \
|
||||
return OpExtInst(result_type, GetGLSLstd450(), opcode, operand_1, operand_2, operand_3); \
|
||||
}
|
||||
|
||||
DEFINE_UNARY(OpFAbs, GLSLstd450FAbs)
|
||||
DEFINE_UNARY(OpSAbs, GLSLstd450SAbs)
|
||||
DEFINE_UNARY(OpRound, GLSLstd450Round)
|
||||
DEFINE_UNARY(OpRoundEven, GLSLstd450RoundEven)
|
||||
DEFINE_UNARY(OpTrunc, GLSLstd450Trunc)
|
||||
DEFINE_UNARY(OpFSign, GLSLstd450FSign)
|
||||
DEFINE_UNARY(OpSSign, GLSLstd450SSign)
|
||||
DEFINE_UNARY(OpFloor, GLSLstd450Floor)
|
||||
DEFINE_UNARY(OpCeil, GLSLstd450Ceil)
|
||||
DEFINE_UNARY(OpFract, GLSLstd450Fract)
|
||||
DEFINE_UNARY(OpSin, GLSLstd450Sin)
|
||||
DEFINE_UNARY(OpCos, GLSLstd450Cos)
|
||||
DEFINE_UNARY(OpAsin, GLSLstd450Asin)
|
||||
DEFINE_UNARY(OpAcos, GLSLstd450Acos)
|
||||
DEFINE_BINARY(OpPow, GLSLstd450Pow)
|
||||
DEFINE_UNARY(OpExp, GLSLstd450Exp)
|
||||
DEFINE_UNARY(OpLog, GLSLstd450Log)
|
||||
DEFINE_UNARY(OpExp2, GLSLstd450Exp2)
|
||||
DEFINE_UNARY(OpLog2, GLSLstd450Log2)
|
||||
DEFINE_UNARY(OpSqrt, GLSLstd450Sqrt)
|
||||
DEFINE_UNARY(OpInverseSqrt, GLSLstd450InverseSqrt)
|
||||
DEFINE_BINARY(OpFMin, GLSLstd450FMin)
|
||||
DEFINE_BINARY(OpUMin, GLSLstd450UMin)
|
||||
DEFINE_BINARY(OpSMin, GLSLstd450SMin)
|
||||
DEFINE_BINARY(OpFMax, GLSLstd450FMax)
|
||||
DEFINE_BINARY(OpUMax, GLSLstd450UMax)
|
||||
DEFINE_BINARY(OpSMax, GLSLstd450SMax)
|
||||
DEFINE_TRINARY(OpFClamp, GLSLstd450FClamp)
|
||||
DEFINE_TRINARY(OpUClamp, GLSLstd450UClamp)
|
||||
DEFINE_TRINARY(OpSClamp, GLSLstd450SClamp)
|
||||
DEFINE_TRINARY(OpFma, GLSLstd450Fma)
|
||||
DEFINE_UNARY(OpPackHalf2x16, GLSLstd450PackHalf2x16)
|
||||
DEFINE_UNARY(OpUnpackHalf2x16, GLSLstd450UnpackHalf2x16)
|
||||
DEFINE_UNARY(OpFindILsb, GLSLstd450FindILsb)
|
||||
DEFINE_UNARY(OpFindSMsb, GLSLstd450FindSMsb)
|
||||
DEFINE_UNARY(OpFindUMsb, GLSLstd450FindUMsb)
|
||||
DEFINE_UNARY(OpInterpolateAtCentroid, GLSLstd450InterpolateAtCentroid)
|
||||
DEFINE_BINARY(OpInterpolateAtSample, GLSLstd450InterpolateAtSample)
|
||||
DEFINE_BINARY(OpInterpolateAtOffset, GLSLstd450InterpolateAtOffset)
|
||||
} // namespace Sirit
|
83
externals/sirit/src/instructions/flow.cpp
vendored
Executable file
83
externals/sirit/src/instructions/flow.cpp
vendored
Executable file
@@ -0,0 +1,83 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
#include "common_types.h"
|
||||
#include "op.h"
|
||||
#include "sirit/sirit.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
Id Module::OpLoopMerge(Id merge_block, Id continue_target, spv::LoopControlMask loop_control,
|
||||
const std::vector<Id>& literals) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpLoopMerge)};
|
||||
op->Add(merge_block);
|
||||
op->Add(continue_target);
|
||||
op->Add(static_cast<u32>(loop_control));
|
||||
op->Add(literals);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpSelectionMerge(Id merge_block, spv::SelectionControlMask selection_control) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpSelectionMerge)};
|
||||
op->Add(merge_block);
|
||||
op->Add(static_cast<u32>(selection_control));
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpLabel() {
|
||||
return code_store.emplace_back(std::make_unique<Op>(spv::Op::OpLabel, bound++)).get();
|
||||
}
|
||||
|
||||
Id Module::OpBranch(Id target_label) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpBranch)};
|
||||
op->Add(target_label);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpBranchConditional(Id condition, Id true_label, Id false_label, u32 true_weight,
|
||||
u32 false_weight) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpBranchConditional)};
|
||||
op->Add(condition);
|
||||
op->Add(true_label);
|
||||
op->Add(false_label);
|
||||
if (true_weight != 0 || false_weight != 0) {
|
||||
op->Add(true_weight);
|
||||
op->Add(false_weight);
|
||||
}
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpSwitch(Id selector, Id default_label, const std::vector<Literal>& literals,
|
||||
const std::vector<Id>& labels) {
|
||||
const std::size_t size = literals.size();
|
||||
assert(literals.size() == labels.size());
|
||||
auto op{std::make_unique<Op>(spv::Op::OpSwitch)};
|
||||
op->Add(selector);
|
||||
op->Add(default_label);
|
||||
for (std::size_t i = 0; i < size; ++i) {
|
||||
op->Add(literals[i]);
|
||||
op->Add(labels[i]);
|
||||
}
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpReturn() {
|
||||
return AddCode(spv::Op::OpReturn);
|
||||
}
|
||||
|
||||
Id Module::OpReturnValue(Id value) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpReturnValue)};
|
||||
op->Add(value);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpKill() {
|
||||
return AddCode(std::make_unique<Op>(spv::Op::OpKill));
|
||||
}
|
||||
|
||||
} // namespace Sirit
|
31
externals/sirit/src/instructions/function.cpp
vendored
Executable file
31
externals/sirit/src/instructions/function.cpp
vendored
Executable file
@@ -0,0 +1,31 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include "common_types.h"
|
||||
#include "op.h"
|
||||
#include "sirit/sirit.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
Id Module::OpFunction(Id result_type, spv::FunctionControlMask function_control, Id function_type) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpFunction, bound++, result_type)};
|
||||
op->Add(static_cast<u32>(function_control));
|
||||
op->Add(function_type);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpFunctionEnd() {
|
||||
return AddCode(spv::Op::OpFunctionEnd);
|
||||
}
|
||||
|
||||
Id Module::OpFunctionCall(Id result_type, Id function, const std::vector<Id>& arguments) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpFunctionCall, bound++, result_type)};
|
||||
op->Add(function);
|
||||
op->Add(arguments);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
} // namespace Sirit
|
51
externals/sirit/src/instructions/group.cpp
vendored
Executable file
51
externals/sirit/src/instructions/group.cpp
vendored
Executable file
@@ -0,0 +1,51 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include "op.h"
|
||||
#include "sirit/sirit.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
Id Module::OpSubgroupBallotKHR(Id result_type, Id predicate) {
|
||||
auto op = std::make_unique<Op>(spv::Op::OpSubgroupBallotKHR, bound++, result_type);
|
||||
op->Add(predicate);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpSubgroupReadInvocationKHR(Id result_type, Id value, Id index) {
|
||||
auto op = std::make_unique<Op>(spv::Op::OpSubgroupReadInvocationKHR, bound++, result_type);
|
||||
op->Add(value);
|
||||
op->Add(index);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpSubgroupAllKHR(Id result_type, Id predicate) {
|
||||
auto op = std::make_unique<Op>(spv::Op::OpSubgroupAllKHR, bound++, result_type);
|
||||
op->Add(predicate);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpSubgroupAnyKHR(Id result_type, Id predicate) {
|
||||
auto op = std::make_unique<Op>(spv::Op::OpSubgroupAnyKHR, bound++, result_type);
|
||||
op->Add(predicate);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpSubgroupAllEqualKHR(Id result_type, Id predicate) {
|
||||
auto op = std::make_unique<Op>(spv::Op::OpSubgroupAllEqualKHR, bound++, result_type);
|
||||
op->Add(predicate);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpGroupNonUniformShuffleXor(Id result_type, spv::Scope scope, Id value, Id mask) {
|
||||
auto op = std::make_unique<Op>(spv::Op::OpGroupNonUniformShuffleXor, bound++, result_type);
|
||||
op->Add(static_cast<u32>(scope));
|
||||
op->Add(value);
|
||||
op->Add(mask);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
} // namespace Sirit
|
124
externals/sirit/src/instructions/image.cpp
vendored
Executable file
124
externals/sirit/src/instructions/image.cpp
vendored
Executable file
@@ -0,0 +1,124 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include "common_types.h"
|
||||
#include "op.h"
|
||||
#include "sirit/sirit.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
static void AddImageOperands(Op* op, std::optional<spv::ImageOperandsMask> image_operands,
|
||||
const std::vector<Id>& operands) {
|
||||
if (!image_operands)
|
||||
return;
|
||||
op->Add(static_cast<u32>(*image_operands));
|
||||
op->Add(operands);
|
||||
}
|
||||
|
||||
#define DEFINE_IMAGE_OP(opcode) \
|
||||
Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, \
|
||||
std::optional<spv::ImageOperandsMask> image_operands, \
|
||||
const std::vector<Id>& operands) { \
|
||||
auto op{std::make_unique<Op>(spv::Op::opcode, bound++, result_type)}; \
|
||||
op->Add(sampled_image); \
|
||||
op->Add(coordinate); \
|
||||
AddImageOperands(op.get(), image_operands, operands); \
|
||||
return AddCode(std::move(op)); \
|
||||
}
|
||||
|
||||
#define DEFINE_IMAGE_EXP_OP(opcode) \
|
||||
Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, \
|
||||
spv::ImageOperandsMask image_operands, const std::vector<Id>& operands) { \
|
||||
auto op{std::make_unique<Op>(spv::Op::opcode, bound++, result_type)}; \
|
||||
op->Add(sampled_image); \
|
||||
op->Add(coordinate); \
|
||||
op->Add(static_cast<u32>(image_operands)); \
|
||||
op->Add(operands); \
|
||||
return AddCode(std::move(op)); \
|
||||
}
|
||||
|
||||
#define DEFINE_IMAGE_EXTRA_OP(opcode) \
|
||||
Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, Id extra, \
|
||||
std::optional<spv::ImageOperandsMask> image_operands, \
|
||||
const std::vector<Id>& operands) { \
|
||||
auto op{std::make_unique<Op>(spv::Op::opcode, bound++, result_type)}; \
|
||||
op->Add(sampled_image); \
|
||||
op->Add(coordinate); \
|
||||
op->Add(extra); \
|
||||
AddImageOperands(op.get(), image_operands, operands); \
|
||||
return AddCode(std::move(op)); \
|
||||
}
|
||||
|
||||
#define DEFINE_IMAGE_EXTRA_EXP_OP(opcode) \
|
||||
Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, Id extra, \
|
||||
spv::ImageOperandsMask image_operands, const std::vector<Id>& operands) { \
|
||||
auto op{std::make_unique<Op>(spv::Op::opcode, bound++, result_type)}; \
|
||||
op->Add(sampled_image); \
|
||||
op->Add(coordinate); \
|
||||
op->Add(extra); \
|
||||
op->Add(static_cast<u32>(image_operands)); \
|
||||
op->Add(operands); \
|
||||
return AddCode(std::move(op)); \
|
||||
}
|
||||
|
||||
#define DEFINE_IMAGE_QUERY_OP(opcode) \
|
||||
Id Module::opcode(Id result_type, Id image) { \
|
||||
auto op{std::make_unique<Op>(spv::Op::opcode, bound++, result_type)}; \
|
||||
op->Add(image); \
|
||||
return AddCode(std::move(op)); \
|
||||
}
|
||||
|
||||
#define DEFINE_IMAGE_QUERY_BIN_OP(opcode) \
|
||||
Id Module::opcode(Id result_type, Id image, Id extra) { \
|
||||
auto op{std::make_unique<Op>(spv::Op::opcode, bound++, result_type)}; \
|
||||
op->Add(image); \
|
||||
op->Add(extra); \
|
||||
return AddCode(std::move(op)); \
|
||||
}
|
||||
|
||||
DEFINE_IMAGE_OP(OpImageSampleImplicitLod)
|
||||
DEFINE_IMAGE_EXP_OP(OpImageSampleExplicitLod)
|
||||
DEFINE_IMAGE_EXTRA_OP(OpImageSampleDrefImplicitLod)
|
||||
DEFINE_IMAGE_EXTRA_EXP_OP(OpImageSampleDrefExplicitLod)
|
||||
DEFINE_IMAGE_OP(OpImageSampleProjImplicitLod)
|
||||
DEFINE_IMAGE_EXP_OP(OpImageSampleProjExplicitLod)
|
||||
DEFINE_IMAGE_EXTRA_OP(OpImageSampleProjDrefImplicitLod)
|
||||
DEFINE_IMAGE_EXTRA_EXP_OP(OpImageSampleProjDrefExplicitLod)
|
||||
DEFINE_IMAGE_OP(OpImageFetch)
|
||||
DEFINE_IMAGE_EXTRA_OP(OpImageGather)
|
||||
DEFINE_IMAGE_EXTRA_OP(OpImageDrefGather)
|
||||
DEFINE_IMAGE_OP(OpImageRead)
|
||||
DEFINE_IMAGE_QUERY_BIN_OP(OpImageQuerySizeLod)
|
||||
DEFINE_IMAGE_QUERY_OP(OpImageQuerySize)
|
||||
DEFINE_IMAGE_QUERY_BIN_OP(OpImageQueryLod)
|
||||
DEFINE_IMAGE_QUERY_OP(OpImageQueryLevels)
|
||||
DEFINE_IMAGE_QUERY_OP(OpImageQuerySamples)
|
||||
|
||||
Id Module::OpSampledImage(Id result_type, Id image, Id sampler) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpSampledImage, bound++, result_type)};
|
||||
op->Add(image);
|
||||
op->Add(sampler);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpImageWrite(Id image, Id coordinate, Id texel,
|
||||
std::optional<spv::ImageOperandsMask> image_operands,
|
||||
const std::vector<Id>& operands) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpImageWrite)};
|
||||
op->Add(image);
|
||||
op->Add(coordinate);
|
||||
op->Add(texel);
|
||||
AddImageOperands(op.get(), image_operands, operands);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpImage(Id result_type, Id sampled_image) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpImage, bound++, result_type)};
|
||||
op->Add(sampled_image);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
} // namespace Sirit
|
71
externals/sirit/src/instructions/logical.cpp
vendored
Executable file
71
externals/sirit/src/instructions/logical.cpp
vendored
Executable file
@@ -0,0 +1,71 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include "common_types.h"
|
||||
#include "op.h"
|
||||
#include "sirit/sirit.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
#define DEFINE_UNARY(funcname, opcode) \
|
||||
Id Module::funcname(Id result_type, Id operand) { \
|
||||
auto op{std::make_unique<Op>(opcode, bound++, result_type)}; \
|
||||
op->Add(operand); \
|
||||
return AddCode(std::move(op)); \
|
||||
}
|
||||
|
||||
#define DEFINE_BINARY(funcname, opcode) \
|
||||
Id Module::funcname(Id result_type, Id operand_1, Id operand_2) { \
|
||||
auto op{std::make_unique<Op>(opcode, bound++, result_type)}; \
|
||||
op->Add(operand_1); \
|
||||
op->Add(operand_2); \
|
||||
return AddCode(std::move(op)); \
|
||||
}
|
||||
|
||||
#define DEFINE_TRINARY(funcname, opcode) \
|
||||
Id Module::funcname(Id result_type, Id operand_1, Id operand_2, Id operand_3) { \
|
||||
auto op{std::make_unique<Op>(opcode, bound++, result_type)}; \
|
||||
op->Add(operand_1); \
|
||||
op->Add(operand_2); \
|
||||
op->Add(operand_3); \
|
||||
return AddCode(std::move(op)); \
|
||||
}
|
||||
|
||||
DEFINE_UNARY(OpAny, spv::Op::OpAny)
|
||||
DEFINE_UNARY(OpAll, spv::Op::OpAll)
|
||||
DEFINE_UNARY(OpIsNan, spv::Op::OpIsNan)
|
||||
DEFINE_UNARY(OpIsInf, spv::Op::OpIsInf)
|
||||
DEFINE_BINARY(OpLogicalEqual, spv::Op::OpLogicalEqual)
|
||||
DEFINE_BINARY(OpLogicalNotEqual, spv::Op::OpLogicalNotEqual)
|
||||
DEFINE_BINARY(OpLogicalOr, spv::Op::OpLogicalOr)
|
||||
DEFINE_BINARY(OpLogicalAnd, spv::Op::OpLogicalAnd)
|
||||
DEFINE_UNARY(OpLogicalNot, spv::Op::OpLogicalNot)
|
||||
DEFINE_TRINARY(OpSelect, spv::Op::OpSelect)
|
||||
DEFINE_BINARY(OpIEqual, spv::Op::OpIEqual)
|
||||
DEFINE_BINARY(OpINotEqual, spv::Op::OpINotEqual)
|
||||
DEFINE_BINARY(OpUGreaterThan, spv::Op::OpUGreaterThan)
|
||||
DEFINE_BINARY(OpSGreaterThan, spv::Op::OpSGreaterThan)
|
||||
DEFINE_BINARY(OpUGreaterThanEqual, spv::Op::OpUGreaterThanEqual)
|
||||
DEFINE_BINARY(OpSGreaterThanEqual, spv::Op::OpSGreaterThanEqual)
|
||||
DEFINE_BINARY(OpULessThan, spv::Op::OpULessThan)
|
||||
DEFINE_BINARY(OpSLessThan, spv::Op::OpSLessThan)
|
||||
DEFINE_BINARY(OpULessThanEqual, spv::Op::OpULessThanEqual)
|
||||
DEFINE_BINARY(OpSLessThanEqual, spv::Op::OpSLessThanEqual)
|
||||
DEFINE_BINARY(OpFOrdEqual, spv::Op::OpFOrdEqual)
|
||||
DEFINE_BINARY(OpFUnordEqual, spv::Op::OpFUnordEqual)
|
||||
DEFINE_BINARY(OpFOrdNotEqual, spv::Op::OpFOrdNotEqual)
|
||||
DEFINE_BINARY(OpFUnordNotEqual, spv::Op::OpFUnordNotEqual)
|
||||
DEFINE_BINARY(OpFOrdLessThan, spv::Op::OpFOrdLessThan)
|
||||
DEFINE_BINARY(OpFUnordLessThan, spv::Op::OpFUnordLessThan)
|
||||
DEFINE_BINARY(OpFOrdGreaterThan, spv::Op::OpFOrdGreaterThan)
|
||||
DEFINE_BINARY(OpFUnordGreaterThan, spv::Op::OpFUnordGreaterThan)
|
||||
DEFINE_BINARY(OpFOrdLessThanEqual, spv::Op::OpFOrdLessThanEqual)
|
||||
DEFINE_BINARY(OpFUnordLessThanEqual, spv::Op::OpFUnordLessThanEqual)
|
||||
DEFINE_BINARY(OpFOrdGreaterThanEqual, spv::Op::OpFOrdGreaterThanEqual)
|
||||
DEFINE_BINARY(OpFUnordGreaterThanEqual, spv::Op::OpFUnordGreaterThanEqual)
|
||||
|
||||
} // namespace Sirit
|
95
externals/sirit/src/instructions/memory.cpp
vendored
Executable file
95
externals/sirit/src/instructions/memory.cpp
vendored
Executable file
@@ -0,0 +1,95 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include "op.h"
|
||||
#include "sirit/sirit.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
Id Module::OpVariable(Id result_type, spv::StorageClass storage_class, Id initializer) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpVariable, bound++, result_type)};
|
||||
op->Add(static_cast<u32>(storage_class));
|
||||
if (initializer) {
|
||||
op->Add(initializer);
|
||||
}
|
||||
return code_store.emplace_back(std::move(op)).get();
|
||||
}
|
||||
|
||||
Id Module::OpImageTexelPointer(Id result_type, Id image, Id coordinate, Id sample) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpImageTexelPointer, bound++, result_type)};
|
||||
op->Add(image);
|
||||
op->Add(coordinate);
|
||||
op->Add(sample);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpLoad(Id result_type, Id pointer, std::optional<spv::MemoryAccessMask> memory_access) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpLoad, bound++, result_type)};
|
||||
op->Add(pointer);
|
||||
if (memory_access) {
|
||||
op->Add(static_cast<u32>(*memory_access));
|
||||
}
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpStore(Id pointer, Id object, std::optional<spv::MemoryAccessMask> memory_access) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpStore)};
|
||||
op->Add(pointer);
|
||||
op->Add(object);
|
||||
if (memory_access) {
|
||||
op->Add(static_cast<u32>(*memory_access));
|
||||
}
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpAccessChain(Id result_type, Id base, const std::vector<Id>& indexes) {
|
||||
assert(indexes.size() > 0);
|
||||
auto op{std::make_unique<Op>(spv::Op::OpAccessChain, bound++, result_type)};
|
||||
op->Add(base);
|
||||
op->Add(indexes);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpVectorExtractDynamic(Id result_type, Id vector, Id index) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpVectorExtractDynamic, bound++, result_type)};
|
||||
op->Add(vector);
|
||||
op->Add(index);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpVectorInsertDynamic(Id result_type, Id vector, Id component, Id index) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpVectorInsertDynamic, bound++, result_type)};
|
||||
op->Add(vector);
|
||||
op->Add(component);
|
||||
op->Add(index);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpCompositeInsert(Id result_type, Id object, Id composite,
|
||||
const std::vector<Literal>& indexes) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpCompositeInsert, bound++, result_type)};
|
||||
op->Add(object);
|
||||
op->Add(composite);
|
||||
op->Add(indexes);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpCompositeExtract(Id result_type, Id composite, const std::vector<Literal>& indexes) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpCompositeExtract, bound++, result_type)};
|
||||
op->Add(composite);
|
||||
op->Add(indexes);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::OpCompositeConstruct(Id result_type, const std::vector<Id>& ids) {
|
||||
assert(ids.size() >= 1);
|
||||
auto op{std::make_unique<Op>(spv::Op::OpCompositeConstruct, bound++, result_type)};
|
||||
op->Add(ids);
|
||||
return AddCode(std::move(op));
|
||||
}
|
||||
|
||||
} // namespace Sirit
|
24
externals/sirit/src/instructions/misc.cpp
vendored
Executable file
24
externals/sirit/src/instructions/misc.cpp
vendored
Executable file
@@ -0,0 +1,24 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include "op.h"
|
||||
#include "sirit/sirit.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
Id Module::OpUndef(Id result_type) {
|
||||
return AddCode(std::make_unique<Op>(spv::Op::OpUndef, bound++, result_type));
|
||||
}
|
||||
|
||||
Id Module::OpEmitVertex() {
|
||||
return AddCode(std::make_unique<Op>(spv::Op::OpEmitVertex));
|
||||
}
|
||||
|
||||
Id Module::OpEndPrimitive() {
|
||||
return AddCode(std::make_unique<Op>(spv::Op::OpEndPrimitive));
|
||||
}
|
||||
|
||||
} // namespace Sirit
|
141
externals/sirit/src/instructions/type.cpp
vendored
Executable file
141
externals/sirit/src/instructions/type.cpp
vendored
Executable file
@@ -0,0 +1,141 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include "op.h"
|
||||
#include "sirit/sirit.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
Id Module::TypeVoid() {
|
||||
return AddDeclaration(std::make_unique<Op>(spv::Op::OpTypeVoid, bound));
|
||||
}
|
||||
|
||||
Id Module::TypeBool() {
|
||||
return AddDeclaration(std::make_unique<Op>(spv::Op::OpTypeBool, bound));
|
||||
}
|
||||
|
||||
Id Module::TypeInt(int width, bool is_signed) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpTypeInt, bound)};
|
||||
op->Add(width);
|
||||
op->Add(is_signed ? 1 : 0);
|
||||
return AddDeclaration(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::TypeFloat(int width) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpTypeFloat, bound)};
|
||||
op->Add(width);
|
||||
return AddDeclaration(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::TypeVector(Id component_type, int component_count) {
|
||||
assert(component_count >= 2);
|
||||
auto op{std::make_unique<Op>(spv::Op::OpTypeVector, bound)};
|
||||
op->Add(component_type);
|
||||
op->Add(component_count);
|
||||
return AddDeclaration(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::TypeMatrix(Id column_type, int column_count) {
|
||||
assert(column_count >= 2);
|
||||
auto op{std::make_unique<Op>(spv::Op::OpTypeMatrix, bound)};
|
||||
op->Add(column_type);
|
||||
op->Add(column_count);
|
||||
return AddDeclaration(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::TypeImage(Id sampled_type, spv::Dim dim, int depth, bool arrayed, bool ms, int sampled,
|
||||
spv::ImageFormat image_format,
|
||||
std::optional<spv::AccessQualifier> access_qualifier) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpTypeImage, bound)};
|
||||
op->Add(sampled_type);
|
||||
op->Add(static_cast<u32>(dim));
|
||||
op->Add(depth);
|
||||
op->Add(arrayed ? 1 : 0);
|
||||
op->Add(ms ? 1 : 0);
|
||||
op->Add(sampled);
|
||||
op->Add(static_cast<u32>(image_format));
|
||||
if (access_qualifier.has_value()) {
|
||||
op->Add(static_cast<u32>(access_qualifier.value()));
|
||||
}
|
||||
return AddDeclaration(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::TypeSampler() {
|
||||
return AddDeclaration(std::make_unique<Op>(spv::Op::OpTypeSampler, bound));
|
||||
}
|
||||
|
||||
Id Module::TypeSampledImage(Id image_type) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpTypeSampledImage, bound)};
|
||||
op->Add(image_type);
|
||||
return AddDeclaration(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::TypeArray(Id element_type, Id length) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpTypeArray, bound)};
|
||||
op->Add(element_type);
|
||||
op->Add(length);
|
||||
return AddDeclaration(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::TypeRuntimeArray(Id element_type) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpTypeRuntimeArray, bound)};
|
||||
op->Add(element_type);
|
||||
return AddDeclaration(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::TypeStruct(const std::vector<Id>& members) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpTypeStruct, bound)};
|
||||
op->Add(members);
|
||||
return AddDeclaration(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::TypeOpaque(std::string name) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpTypeOpaque, bound)};
|
||||
op->Add(std::move(name));
|
||||
return AddDeclaration(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::TypePointer(spv::StorageClass storage_class, Id type) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpTypePointer, bound)};
|
||||
op->Add(static_cast<u32>(storage_class));
|
||||
op->Add(type);
|
||||
return AddDeclaration(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::TypeFunction(Id return_type, const std::vector<Id>& arguments) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpTypeFunction, bound)};
|
||||
op->Add(return_type);
|
||||
op->Add(arguments);
|
||||
return AddDeclaration(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::TypeEvent() {
|
||||
return AddDeclaration(std::make_unique<Op>(spv::Op::OpTypeEvent, bound));
|
||||
}
|
||||
|
||||
Id Module::TypeDeviceEvent() {
|
||||
return AddDeclaration(std::make_unique<Op>(spv::Op::OpTypeDeviceEvent, bound));
|
||||
}
|
||||
|
||||
Id Module::TypeReserveId() {
|
||||
return AddDeclaration(std::make_unique<Op>(spv::Op::OpTypeReserveId, bound));
|
||||
}
|
||||
|
||||
Id Module::TypeQueue() {
|
||||
return AddDeclaration(std::make_unique<Op>(spv::Op::OpTypeQueue, bound));
|
||||
}
|
||||
|
||||
Id Module::TypePipe(spv::AccessQualifier access_qualifier) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpTypePipe, bound)};
|
||||
op->Add(static_cast<u32>(access_qualifier));
|
||||
return AddDeclaration(std::move(op));
|
||||
}
|
||||
|
||||
} // namespace Sirit
|
37
externals/sirit/src/literal_number.cpp
vendored
Executable file
37
externals/sirit/src/literal_number.cpp
vendored
Executable file
@@ -0,0 +1,37 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include "literal_number.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
LiteralNumber::LiteralNumber(u64 raw_, bool is_32_)
|
||||
: Operand{OperandType::Number}, raw{raw_}, is_32{is_32_} {}
|
||||
|
||||
LiteralNumber::~LiteralNumber() = default;
|
||||
|
||||
void LiteralNumber::Fetch(Stream& stream) const {
|
||||
if (is_32) {
|
||||
stream.Write(static_cast<u32>(raw));
|
||||
} else {
|
||||
stream.Write(raw);
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t LiteralNumber::GetWordCount() const noexcept {
|
||||
return is_32 ? 1 : 2;
|
||||
}
|
||||
|
||||
bool LiteralNumber::operator==(const Operand& other) const noexcept {
|
||||
if (!EqualType(other)) {
|
||||
return false;
|
||||
}
|
||||
const auto& o{static_cast<const LiteralNumber&>(other)};
|
||||
return o.raw == raw && o.is_32 == is_32;
|
||||
}
|
||||
|
||||
} // namespace Sirit
|
43
externals/sirit/src/literal_number.h
vendored
Executable file
43
externals/sirit/src/literal_number.h
vendored
Executable file
@@ -0,0 +1,43 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
#include "operand.h"
|
||||
#include "stream.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
class LiteralNumber final : public Operand {
|
||||
public:
|
||||
explicit LiteralNumber(u64 raw, bool is_32);
|
||||
~LiteralNumber() override;
|
||||
|
||||
void Fetch(Stream& stream) const override;
|
||||
|
||||
std::size_t GetWordCount() const noexcept override;
|
||||
|
||||
bool operator==(const Operand& other) const noexcept override;
|
||||
|
||||
template <typename T>
|
||||
static std::unique_ptr<LiteralNumber> Create(T value) {
|
||||
static_assert(sizeof(T) == 4 || sizeof(T) == 8);
|
||||
|
||||
u64 raw{};
|
||||
std::memcpy(&raw, &value, sizeof(T));
|
||||
return std::make_unique<LiteralNumber>(raw, sizeof(T) == 4);
|
||||
}
|
||||
|
||||
private:
|
||||
u64 raw{};
|
||||
bool is_32{};
|
||||
};
|
||||
|
||||
} // namespace Sirit
|
33
externals/sirit/src/literal_string.cpp
vendored
Executable file
33
externals/sirit/src/literal_string.cpp
vendored
Executable file
@@ -0,0 +1,33 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include "common_types.h"
|
||||
#include "literal_string.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
LiteralString::LiteralString(std::string string_)
|
||||
: Operand{OperandType::String}, string{std::move(string_)} {}
|
||||
|
||||
LiteralString::~LiteralString() = default;
|
||||
|
||||
void LiteralString::Fetch(Stream& stream) const {
|
||||
stream.Write(string);
|
||||
}
|
||||
|
||||
std::size_t LiteralString::GetWordCount() const noexcept {
|
||||
return string.size() / 4 + 1;
|
||||
}
|
||||
|
||||
bool LiteralString::operator==(const Operand& other) const noexcept {
|
||||
if (!EqualType(other)) {
|
||||
return false;
|
||||
}
|
||||
return static_cast<const LiteralString&>(other).string == string;
|
||||
}
|
||||
|
||||
} // namespace Sirit
|
30
externals/sirit/src/literal_string.h
vendored
Executable file
30
externals/sirit/src/literal_string.h
vendored
Executable file
@@ -0,0 +1,30 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "operand.h"
|
||||
#include "stream.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
class LiteralString final : public Operand {
|
||||
public:
|
||||
LiteralString(std::string string);
|
||||
~LiteralString() override;
|
||||
|
||||
void Fetch(Stream& stream) const override;
|
||||
|
||||
std::size_t GetWordCount() const noexcept override;
|
||||
|
||||
bool operator==(const Operand& other) const noexcept override;
|
||||
|
||||
private:
|
||||
std::string string;
|
||||
};
|
||||
|
||||
} // namespace Sirit
|
135
externals/sirit/src/op.cpp
vendored
Executable file
135
externals/sirit/src/op.cpp
vendored
Executable file
@@ -0,0 +1,135 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
|
||||
#include "common_types.h"
|
||||
#include "literal_number.h"
|
||||
#include "literal_string.h"
|
||||
#include "op.h"
|
||||
#include "operand.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
Op::Op(spv::Op opcode_, std::optional<u32> id_, Id result_type_)
|
||||
: Operand{OperandType::Op}, opcode{opcode_}, result_type{result_type_}, id{id_} {}
|
||||
|
||||
Op::~Op() = default;
|
||||
|
||||
void Op::Fetch(Stream& stream) const {
|
||||
assert(id.has_value());
|
||||
stream.Write(id.value());
|
||||
}
|
||||
|
||||
std::size_t Op::GetWordCount() const noexcept {
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool Op::operator==(const Operand& other) const noexcept {
|
||||
if (!EqualType(other)) {
|
||||
return false;
|
||||
}
|
||||
const auto& op = static_cast<const Op&>(other);
|
||||
if (op.opcode == opcode && result_type == op.result_type &&
|
||||
operands.size() == op.operands.size()) {
|
||||
for (std::size_t i = 0; i < operands.size(); i++) {
|
||||
if (*operands[i] != *op.operands[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Op::Write(Stream& stream) const {
|
||||
stream.Write(static_cast<u16>(opcode), CalculateTotalWords());
|
||||
|
||||
if (result_type) {
|
||||
result_type->Fetch(stream);
|
||||
}
|
||||
if (id.has_value()) {
|
||||
stream.Write(id.value());
|
||||
}
|
||||
for (const auto* operand : operands) {
|
||||
operand->Fetch(stream);
|
||||
}
|
||||
}
|
||||
|
||||
void Op::Sink(std::unique_ptr<Operand> operand) {
|
||||
Add(static_cast<const Operand*>(operand.get()));
|
||||
operand_store.push_back(std::move(operand));
|
||||
}
|
||||
|
||||
void Op::Add(const Literal& literal) {
|
||||
Sink([&] {
|
||||
switch (literal.index()) {
|
||||
case 0:
|
||||
return LiteralNumber::Create(std::get<0>(literal));
|
||||
case 1:
|
||||
return LiteralNumber::Create(std::get<1>(literal));
|
||||
case 2:
|
||||
return LiteralNumber::Create(std::get<2>(literal));
|
||||
case 3:
|
||||
return LiteralNumber::Create(std::get<3>(literal));
|
||||
case 4:
|
||||
return LiteralNumber::Create(std::get<4>(literal));
|
||||
case 5:
|
||||
return LiteralNumber::Create(std::get<5>(literal));
|
||||
default:
|
||||
// Invalid literal type
|
||||
assert(0);
|
||||
abort();
|
||||
}
|
||||
}());
|
||||
}
|
||||
|
||||
void Op::Add(const std::vector<Literal>& literals) {
|
||||
for (const auto& literal : literals) {
|
||||
Add(literal);
|
||||
}
|
||||
}
|
||||
|
||||
void Op::Add(const Operand* operand) {
|
||||
assert(operand);
|
||||
operands.push_back(operand);
|
||||
}
|
||||
|
||||
void Op::Add(u32 integer) {
|
||||
Sink(LiteralNumber::Create(integer));
|
||||
}
|
||||
|
||||
void Op::Add(s32 integer) {
|
||||
Sink(LiteralNumber::Create(integer));
|
||||
}
|
||||
|
||||
void Op::Add(std::string string) {
|
||||
Sink(std::make_unique<LiteralString>(std::move(string)));
|
||||
}
|
||||
|
||||
void Op::Add(const std::vector<Id>& ids) {
|
||||
assert(std::all_of(ids.begin(), ids.end(), [](auto id_) { return id_; }));
|
||||
operands.insert(operands.end(), ids.begin(), ids.end());
|
||||
}
|
||||
|
||||
u16 Op::CalculateTotalWords() const noexcept {
|
||||
std::size_t count = 1;
|
||||
if (result_type) {
|
||||
++count;
|
||||
}
|
||||
if (id.has_value()) {
|
||||
++count;
|
||||
}
|
||||
for (const Operand* operand : operands) {
|
||||
count += operand->GetWordCount();
|
||||
}
|
||||
assert(count < std::numeric_limits<u16>::max());
|
||||
return static_cast<u16>(count);
|
||||
}
|
||||
|
||||
} // namespace Sirit
|
63
externals/sirit/src/op.h
vendored
Executable file
63
externals/sirit/src/op.h
vendored
Executable file
@@ -0,0 +1,63 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include "common_types.h"
|
||||
#include "operand.h"
|
||||
#include "sirit/sirit.h"
|
||||
#include "stream.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
class Op final : public Operand {
|
||||
public:
|
||||
explicit Op(spv::Op opcode, std::optional<u32> id = {}, Id result_type = nullptr);
|
||||
~Op() override;
|
||||
|
||||
void Fetch(Stream& stream) const override;
|
||||
|
||||
std::size_t GetWordCount() const noexcept override;
|
||||
|
||||
bool operator==(const Operand& other) const noexcept override;
|
||||
|
||||
void Write(Stream& stream) const;
|
||||
|
||||
void Sink(std::unique_ptr<Operand> operand);
|
||||
|
||||
void Add(const Literal& literal);
|
||||
|
||||
void Add(const std::vector<Literal>& literals);
|
||||
|
||||
void Add(const Operand* operand);
|
||||
|
||||
void Add(u32 integer);
|
||||
|
||||
void Add(s32 integer);
|
||||
|
||||
void Add(std::string string);
|
||||
|
||||
void Add(const std::vector<Id>& ids);
|
||||
|
||||
private:
|
||||
u16 CalculateTotalWords() const noexcept;
|
||||
|
||||
spv::Op opcode;
|
||||
|
||||
Id result_type;
|
||||
|
||||
std::optional<u32> id;
|
||||
|
||||
std::vector<const Operand*> operands;
|
||||
|
||||
std::vector<std::unique_ptr<Operand>> operand_store;
|
||||
};
|
||||
|
||||
} // namespace Sirit
|
16
externals/sirit/src/operand.cpp
vendored
Executable file
16
externals/sirit/src/operand.cpp
vendored
Executable file
@@ -0,0 +1,16 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include "operand.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
Operand::Operand(OperandType operand_type_) : operand_type{operand_type_} {}
|
||||
|
||||
Operand::~Operand() = default;
|
||||
|
||||
} // namespace Sirit
|
40
externals/sirit/src/operand.h
vendored
Executable file
40
externals/sirit/src/operand.h
vendored
Executable file
@@ -0,0 +1,40 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "stream.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
enum class OperandType { Invalid, Op, Number, String };
|
||||
|
||||
class Operand {
|
||||
public:
|
||||
explicit Operand(OperandType operand_type);
|
||||
virtual ~Operand();
|
||||
|
||||
virtual void Fetch(Stream& stream) const = 0;
|
||||
|
||||
virtual std::size_t GetWordCount() const noexcept = 0;
|
||||
|
||||
virtual bool operator==(const Operand& other) const noexcept = 0;
|
||||
|
||||
bool operator!=(const Operand& other) const noexcept {
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
bool EqualType(const Operand& other) const noexcept {
|
||||
return operand_type == other.operand_type;
|
||||
}
|
||||
|
||||
private:
|
||||
OperandType operand_type;
|
||||
};
|
||||
|
||||
} // namespace Sirit
|
149
externals/sirit/src/sirit.cpp
vendored
Executable file
149
externals/sirit/src/sirit.cpp
vendored
Executable file
@@ -0,0 +1,149 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include "common_types.h"
|
||||
#include "op.h"
|
||||
#include "sirit/sirit.h"
|
||||
#include "stream.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
template <typename T>
|
||||
static void WriteSet(Stream& stream, const T& set) {
|
||||
for (const auto& item : set) {
|
||||
item->Write(stream);
|
||||
}
|
||||
}
|
||||
|
||||
Module::Module(u32 version_) : version{version_} {}
|
||||
|
||||
Module::~Module() = default;
|
||||
|
||||
std::vector<u32> Module::Assemble() const {
|
||||
std::vector<u32> bytes;
|
||||
Stream stream{bytes};
|
||||
|
||||
stream.Write(spv::MagicNumber);
|
||||
stream.Write(version);
|
||||
stream.Write(GENERATOR_MAGIC_NUMBER);
|
||||
stream.Write(bound);
|
||||
stream.Write(static_cast<u32>(0));
|
||||
|
||||
for (const auto capability : capabilities) {
|
||||
Op op(spv::Op::OpCapability);
|
||||
op.Add(static_cast<u32>(capability));
|
||||
op.Write(stream);
|
||||
}
|
||||
|
||||
for (const auto& extension_name : extensions) {
|
||||
Op op(spv::Op::OpExtension);
|
||||
op.Add(extension_name);
|
||||
op.Write(stream);
|
||||
}
|
||||
|
||||
if (glsl_std_450) {
|
||||
glsl_std_450->Write(stream);
|
||||
}
|
||||
|
||||
Op memory_model_ref{spv::Op::OpMemoryModel};
|
||||
memory_model_ref.Add(static_cast<u32>(addressing_model));
|
||||
memory_model_ref.Add(static_cast<u32>(memory_model));
|
||||
memory_model_ref.Write(stream);
|
||||
|
||||
WriteSet(stream, entry_points);
|
||||
WriteSet(stream, execution_modes);
|
||||
WriteSet(stream, debug);
|
||||
WriteSet(stream, annotations);
|
||||
WriteSet(stream, declarations);
|
||||
WriteSet(stream, global_variables);
|
||||
WriteSet(stream, code);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
void Module::AddExtension(std::string extension_name) {
|
||||
extensions.insert(std::move(extension_name));
|
||||
}
|
||||
|
||||
void Module::AddCapability(spv::Capability capability) {
|
||||
capabilities.insert(capability);
|
||||
}
|
||||
|
||||
void Module::SetMemoryModel(spv::AddressingModel addressing_model_, spv::MemoryModel memory_model_) {
|
||||
this->addressing_model = addressing_model_;
|
||||
this->memory_model = memory_model_;
|
||||
}
|
||||
|
||||
void Module::AddEntryPoint(spv::ExecutionModel execution_model, Id entry_point,
|
||||
std::string name, const std::vector<Id>& interfaces) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpEntryPoint)};
|
||||
op->Add(static_cast<u32>(execution_model));
|
||||
op->Add(entry_point);
|
||||
op->Add(std::move(name));
|
||||
op->Add(interfaces);
|
||||
entry_points.push_back(std::move(op));
|
||||
}
|
||||
|
||||
void Module::AddExecutionMode(Id entry_point, spv::ExecutionMode mode,
|
||||
const std::vector<Literal>& literals) {
|
||||
auto op{std::make_unique<Op>(spv::Op::OpExecutionMode)};
|
||||
op->Add(entry_point);
|
||||
op->Add(static_cast<u32>(mode));
|
||||
op->Add(literals);
|
||||
execution_modes.push_back(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::AddLabel(Id label) {
|
||||
assert(label != nullptr);
|
||||
return code.emplace_back(label);
|
||||
}
|
||||
|
||||
Id Module::AddLocalVariable(Id variable) {
|
||||
assert(variable != nullptr);
|
||||
return code.emplace_back(variable);
|
||||
}
|
||||
|
||||
Id Module::AddGlobalVariable(Id variable) {
|
||||
assert(variable);
|
||||
return global_variables.emplace_back(variable);
|
||||
}
|
||||
|
||||
Id Module::AddCode(std::unique_ptr<Op> op) {
|
||||
const Id id = code_store.emplace_back(std::move(op)).get();
|
||||
return code.emplace_back(id);
|
||||
}
|
||||
|
||||
Id Module::AddCode(spv::Op opcode, std::optional<u32> id) {
|
||||
return AddCode(std::make_unique<Op>(opcode, id));
|
||||
}
|
||||
|
||||
Id Module::AddDeclaration(std::unique_ptr<Op> op) {
|
||||
const auto& found{std::find_if(declarations.begin(), declarations.end(),
|
||||
[&op](const auto& other) { return *other == *op; })};
|
||||
if (found != declarations.end()) {
|
||||
return found->get();
|
||||
}
|
||||
const auto id = op.get();
|
||||
declarations.push_back(std::move(op));
|
||||
bound++;
|
||||
return id;
|
||||
}
|
||||
|
||||
void Module::AddAnnotation(std::unique_ptr<Op> op) {
|
||||
annotations.push_back(std::move(op));
|
||||
}
|
||||
|
||||
Id Module::GetGLSLstd450() {
|
||||
if (!glsl_std_450) {
|
||||
glsl_std_450 = std::make_unique<Op>(spv::Op::OpExtInstImport, bound++);
|
||||
glsl_std_450->Add("GLSL.std.450");
|
||||
}
|
||||
return glsl_std_450.get();
|
||||
}
|
||||
|
||||
} // namespace Sirit
|
51
externals/sirit/src/stream.cpp
vendored
Executable file
51
externals/sirit/src/stream.cpp
vendored
Executable file
@@ -0,0 +1,51 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include "stream.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
Stream::Stream(std::vector<u32>& words_) : words{words_} {}
|
||||
|
||||
Stream::~Stream() = default;
|
||||
|
||||
void Stream::Write(std::string_view string) {
|
||||
constexpr std::size_t word_size = 4;
|
||||
const auto size = string.size();
|
||||
const auto read = [string, size](std::size_t offset) {
|
||||
return offset < size ? static_cast<u8>(string[offset]) : u8(0);
|
||||
};
|
||||
|
||||
words.reserve(words.size() + size / word_size + 1);
|
||||
for (std::size_t i = 0; i < size; i += word_size) {
|
||||
Write(read(i), read(i + 1), read(i + 2), read(i + 3));
|
||||
}
|
||||
if (size % word_size == 0) {
|
||||
Write(u32(0));
|
||||
}
|
||||
}
|
||||
|
||||
void Stream::Write(u64 value) {
|
||||
const u32 dword[] = {static_cast<u32>(value), static_cast<u32>(value >> 32)};
|
||||
words.insert(std::begin(words), std::cbegin(dword), std::cend(dword));
|
||||
}
|
||||
|
||||
void Stream::Write(u32 value) {
|
||||
words.push_back(value);
|
||||
}
|
||||
|
||||
void Stream::Write(u16 first, u16 second) {
|
||||
const u32 word = static_cast<u32>(first) | static_cast<u32>(second) << 16;
|
||||
Write(word);
|
||||
}
|
||||
|
||||
void Stream::Write(u8 first, u8 second, u8 third, u8 fourth) {
|
||||
const u32 word = static_cast<u32>(first) | static_cast<u32>(second) << 8 |
|
||||
static_cast<u32>(third) << 16 | static_cast<u32>(fourth) << 24;
|
||||
Write(word);
|
||||
}
|
||||
|
||||
} // namespace Sirit
|
34
externals/sirit/src/stream.h
vendored
Executable file
34
externals/sirit/src/stream.h
vendored
Executable file
@@ -0,0 +1,34 @@
|
||||
/* This file is part of the sirit project.
|
||||
* Copyright (c) 2019 sirit
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include "common_types.h"
|
||||
|
||||
namespace Sirit {
|
||||
|
||||
class Stream {
|
||||
public:
|
||||
explicit Stream(std::vector<u32>& words);
|
||||
~Stream();
|
||||
|
||||
void Write(std::string_view string);
|
||||
|
||||
void Write(u64 value);
|
||||
|
||||
void Write(u32 value);
|
||||
|
||||
void Write(u16 first, u16 second);
|
||||
|
||||
void Write(u8 first, u8 second, u8 third, u8 fourth);
|
||||
|
||||
private:
|
||||
std::vector<u32>& words;
|
||||
};
|
||||
|
||||
} // namespace Sirit
|
Reference in New Issue
Block a user