mirror of
https://git.suyu.dev/suyu/sirit.git
synced 2025-12-27 01:36:46 +01:00
Stream SPIR-V instructions directly to a binary
Before this commit sirit generated a stream of tokens that would then be inserted to the final SPIR-V binary. This design was carried from the initial design of manually inserting opcodes into the code. Now that all instructions but labels are inserted when their respective function is called, the old design can be dropped in favor of generating a valid stream of SPIR-V opcodes. The API for variables is broken, but adopting the new one is trivial. Instead of calling OpVariable and then adding a global or local variable, OpVariable was removed and global or local variables are generated when they are called. Avoiding duplicates is now done with an std::unordered_set instead of using a linear search jumping through vtables.
This commit is contained in:
parent
c4ea8f4b76
commit
0b9ee36247
31 changed files with 651 additions and 1150 deletions
|
|
@ -4,79 +4,58 @@
|
|||
* 3-Clause BSD License
|
||||
*/
|
||||
|
||||
#include "common_types.h"
|
||||
#include "op.h"
|
||||
#include <cassert>
|
||||
|
||||
#include "sirit/sirit.h"
|
||||
|
||||
namespace Sirit {
|
||||
#include "stream.h"
|
||||
|
||||
static void AddImageOperands(Op* op, std::optional<spv::ImageOperandsMask> image_operands,
|
||||
std::span<const Id> operands) {
|
||||
if (!image_operands)
|
||||
return;
|
||||
op->Add(static_cast<u32>(*image_operands));
|
||||
op->Add(operands);
|
||||
}
|
||||
namespace Sirit {
|
||||
|
||||
#define DEFINE_IMAGE_OP(opcode) \
|
||||
Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, \
|
||||
std::optional<spv::ImageOperandsMask> image_operands, \
|
||||
std::span<const 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)); \
|
||||
code->Reserve(6 + operands.size()); \
|
||||
return *code << OpId{spv::Op::opcode, result_type} << sampled_image << coordinate \
|
||||
<< image_operands << operands << EndOp{}; \
|
||||
}
|
||||
|
||||
#define DEFINE_IMAGE_EXP_OP(opcode) \
|
||||
Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, \
|
||||
spv::ImageOperandsMask image_operands, std::span<const 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)); \
|
||||
code->Reserve(7 + operands.size()); \
|
||||
return *code << OpId{spv::Op::OpDecorate, result_type} << sampled_image << coordinate \
|
||||
<< image_operands << operands << EndOp{}; \
|
||||
}
|
||||
|
||||
#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, \
|
||||
std::span<const 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)); \
|
||||
code->Reserve(7 + operands.size()); \
|
||||
return *code << OpId{spv::Op::opcode, result_type} << sampled_image << coordinate << extra \
|
||||
<< image_operands << operands << EndOp{}; \
|
||||
}
|
||||
|
||||
#define DEFINE_IMAGE_EXTRA_EXP_OP(opcode) \
|
||||
Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, Id extra, \
|
||||
spv::ImageOperandsMask image_operands, std::span<const 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)); \
|
||||
code->Reserve(8 + operands.size()); \
|
||||
return *code << OpId{spv::Op::opcode, result_type} << sampled_image << coordinate << extra \
|
||||
<< image_operands << operands << EndOp{}; \
|
||||
}
|
||||
|
||||
#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)); \
|
||||
code->Reserve(5); \
|
||||
return *code << OpId{spv::Op::opcode, result_type} << image << EndOp{}; \
|
||||
}
|
||||
|
||||
#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)); \
|
||||
code->Reserve(5); \
|
||||
return *code << OpId{spv::Op::OpDecorate, result_type} << image << extra << EndOp{}; \
|
||||
}
|
||||
|
||||
DEFINE_IMAGE_OP(OpImageSampleImplicitLod)
|
||||
|
|
@ -98,27 +77,22 @@ 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));
|
||||
code->Reserve(5);
|
||||
return *code << OpId{spv::Op::OpSampledImage, result_type} << image << sampler << EndOp{};
|
||||
}
|
||||
|
||||
Id Module::OpImageWrite(Id image, Id coordinate, Id texel,
|
||||
std::optional<spv::ImageOperandsMask> image_operands,
|
||||
std::span<const 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));
|
||||
assert(image_operands.has_value() != operands.empty());
|
||||
code->Reserve(5 + operands.size());
|
||||
return *code << spv::Op::OpImageWrite << image << coordinate << texel << image_operands
|
||||
<< operands << EndOp{};
|
||||
}
|
||||
|
||||
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));
|
||||
code->Reserve(4);
|
||||
return *code << OpId{spv::Op::OpImage, result_type} << sampled_image << EndOp{};
|
||||
}
|
||||
|
||||
} // namespace Sirit
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue