|
@@ -16,7 +16,7 @@
|
|
namespace clang {
|
|
namespace clang {
|
|
namespace spirv {
|
|
namespace spirv {
|
|
|
|
|
|
-static_assert(spv::Version == 0x00010000 && spv::Revision == 12,
|
|
|
|
|
|
+static_assert(spv::Version == 0x00010200 && spv::Revision == 3,
|
|
"Needs to regenerate outdated InstBuilder");
|
|
"Needs to regenerate outdated InstBuilder");
|
|
|
|
|
|
namespace {
|
|
namespace {
|
|
@@ -24,6 +24,10 @@ inline bool bitEnumContains(spv::ImageOperandsMask bits,
|
|
spv::ImageOperandsMask bit) {
|
|
spv::ImageOperandsMask bit) {
|
|
return (uint32_t(bits) & uint32_t(bit)) != 0;
|
|
return (uint32_t(bits) & uint32_t(bit)) != 0;
|
|
}
|
|
}
|
|
|
|
+inline bool bitEnumContains(spv::LoopControlMask bits,
|
|
|
|
+ spv::LoopControlMask bit) {
|
|
|
|
+ return (uint32_t(bits) & uint32_t(bit)) != 0;
|
|
|
|
+}
|
|
inline bool bitEnumContains(spv::MemoryAccessMask bits,
|
|
inline bool bitEnumContains(spv::MemoryAccessMask bits,
|
|
spv::MemoryAccessMask bit) {
|
|
spv::MemoryAccessMask bit) {
|
|
return (uint32_t(bits) & uint32_t(bit)) != 0;
|
|
return (uint32_t(bits) & uint32_t(bit)) != 0;
|
|
@@ -5445,7 +5449,7 @@ InstBuilder &InstBuilder::opLoopMerge(uint32_t merge_block,
|
|
TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpLoopMerge));
|
|
TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpLoopMerge));
|
|
TheInst.emplace_back(merge_block);
|
|
TheInst.emplace_back(merge_block);
|
|
TheInst.emplace_back(continue_target);
|
|
TheInst.emplace_back(continue_target);
|
|
- TheInst.emplace_back(static_cast<uint32_t>(loop_control));
|
|
|
|
|
|
+ encodeLoopControl(loop_control);
|
|
|
|
|
|
return *this;
|
|
return *this;
|
|
}
|
|
}
|
|
@@ -7166,6 +7170,265 @@ InstBuilder &InstBuilder::opImageSparseRead(
|
|
return *this;
|
|
return *this;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+InstBuilder &InstBuilder::opSizeOf(uint32_t result_type, uint32_t result_id,
|
|
|
|
+ uint32_t pointer) {
|
|
|
|
+ if (!TheInst.empty()) {
|
|
|
|
+ TheStatus = Status::NestedInst;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+ if (result_type == 0) {
|
|
|
|
+ TheStatus = Status::ZeroResultType;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+ if (result_id == 0) {
|
|
|
|
+ TheStatus = Status::ZeroResultId;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ TheInst.reserve(4);
|
|
|
|
+ TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpSizeOf));
|
|
|
|
+ TheInst.emplace_back(result_type);
|
|
|
|
+ TheInst.emplace_back(result_id);
|
|
|
|
+ TheInst.emplace_back(pointer);
|
|
|
|
+
|
|
|
|
+ return *this;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+InstBuilder &InstBuilder::opTypePipeStorage(uint32_t result_id) {
|
|
|
|
+ if (!TheInst.empty()) {
|
|
|
|
+ TheStatus = Status::NestedInst;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+ if (result_id == 0) {
|
|
|
|
+ TheStatus = Status::ZeroResultId;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ TheInst.reserve(2);
|
|
|
|
+ TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypePipeStorage));
|
|
|
|
+ TheInst.emplace_back(result_id);
|
|
|
|
+
|
|
|
|
+ return *this;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+InstBuilder &InstBuilder::opConstantPipeStorage(uint32_t result_type,
|
|
|
|
+ uint32_t result_id,
|
|
|
|
+ uint32_t packet_size,
|
|
|
|
+ uint32_t packet_alignment,
|
|
|
|
+ uint32_t capacity) {
|
|
|
|
+ if (!TheInst.empty()) {
|
|
|
|
+ TheStatus = Status::NestedInst;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+ if (result_type == 0) {
|
|
|
|
+ TheStatus = Status::ZeroResultType;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+ if (result_id == 0) {
|
|
|
|
+ TheStatus = Status::ZeroResultId;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ TheInst.reserve(6);
|
|
|
|
+ TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpConstantPipeStorage));
|
|
|
|
+ TheInst.emplace_back(result_type);
|
|
|
|
+ TheInst.emplace_back(result_id);
|
|
|
|
+ TheInst.emplace_back(packet_size);
|
|
|
|
+ TheInst.emplace_back(packet_alignment);
|
|
|
|
+ TheInst.emplace_back(capacity);
|
|
|
|
+
|
|
|
|
+ return *this;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+InstBuilder &InstBuilder::opCreatePipeFromPipeStorage(uint32_t result_type,
|
|
|
|
+ uint32_t result_id,
|
|
|
|
+ uint32_t pipe_storage) {
|
|
|
|
+ if (!TheInst.empty()) {
|
|
|
|
+ TheStatus = Status::NestedInst;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+ if (result_type == 0) {
|
|
|
|
+ TheStatus = Status::ZeroResultType;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+ if (result_id == 0) {
|
|
|
|
+ TheStatus = Status::ZeroResultId;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ TheInst.reserve(4);
|
|
|
|
+ TheInst.emplace_back(
|
|
|
|
+ static_cast<uint32_t>(spv::Op::OpCreatePipeFromPipeStorage));
|
|
|
|
+ TheInst.emplace_back(result_type);
|
|
|
|
+ TheInst.emplace_back(result_id);
|
|
|
|
+ TheInst.emplace_back(pipe_storage);
|
|
|
|
+
|
|
|
|
+ return *this;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+InstBuilder &InstBuilder::opGetKernelLocalSizeForSubgroupCount(
|
|
|
|
+ uint32_t result_type, uint32_t result_id, uint32_t subgroup_count,
|
|
|
|
+ uint32_t invoke, uint32_t param, uint32_t param_size,
|
|
|
|
+ uint32_t param_align) {
|
|
|
|
+ if (!TheInst.empty()) {
|
|
|
|
+ TheStatus = Status::NestedInst;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+ if (result_type == 0) {
|
|
|
|
+ TheStatus = Status::ZeroResultType;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+ if (result_id == 0) {
|
|
|
|
+ TheStatus = Status::ZeroResultId;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ TheInst.reserve(8);
|
|
|
|
+ TheInst.emplace_back(
|
|
|
|
+ static_cast<uint32_t>(spv::Op::OpGetKernelLocalSizeForSubgroupCount));
|
|
|
|
+ TheInst.emplace_back(result_type);
|
|
|
|
+ TheInst.emplace_back(result_id);
|
|
|
|
+ TheInst.emplace_back(subgroup_count);
|
|
|
|
+ TheInst.emplace_back(invoke);
|
|
|
|
+ TheInst.emplace_back(param);
|
|
|
|
+ TheInst.emplace_back(param_size);
|
|
|
|
+ TheInst.emplace_back(param_align);
|
|
|
|
+
|
|
|
|
+ return *this;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+InstBuilder &InstBuilder::opGetKernelMaxNumSubgroups(
|
|
|
|
+ uint32_t result_type, uint32_t result_id, uint32_t invoke, uint32_t param,
|
|
|
|
+ uint32_t param_size, uint32_t param_align) {
|
|
|
|
+ if (!TheInst.empty()) {
|
|
|
|
+ TheStatus = Status::NestedInst;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+ if (result_type == 0) {
|
|
|
|
+ TheStatus = Status::ZeroResultType;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+ if (result_id == 0) {
|
|
|
|
+ TheStatus = Status::ZeroResultId;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ TheInst.reserve(7);
|
|
|
|
+ TheInst.emplace_back(
|
|
|
|
+ static_cast<uint32_t>(spv::Op::OpGetKernelMaxNumSubgroups));
|
|
|
|
+ TheInst.emplace_back(result_type);
|
|
|
|
+ TheInst.emplace_back(result_id);
|
|
|
|
+ TheInst.emplace_back(invoke);
|
|
|
|
+ TheInst.emplace_back(param);
|
|
|
|
+ TheInst.emplace_back(param_size);
|
|
|
|
+ TheInst.emplace_back(param_align);
|
|
|
|
+
|
|
|
|
+ return *this;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+InstBuilder &InstBuilder::opTypeNamedBarrier(uint32_t result_id) {
|
|
|
|
+ if (!TheInst.empty()) {
|
|
|
|
+ TheStatus = Status::NestedInst;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+ if (result_id == 0) {
|
|
|
|
+ TheStatus = Status::ZeroResultId;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ TheInst.reserve(2);
|
|
|
|
+ TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeNamedBarrier));
|
|
|
|
+ TheInst.emplace_back(result_id);
|
|
|
|
+
|
|
|
|
+ return *this;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+InstBuilder &InstBuilder::opNamedBarrierInitialize(uint32_t result_type,
|
|
|
|
+ uint32_t result_id,
|
|
|
|
+ uint32_t subgroup_count) {
|
|
|
|
+ if (!TheInst.empty()) {
|
|
|
|
+ TheStatus = Status::NestedInst;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+ if (result_type == 0) {
|
|
|
|
+ TheStatus = Status::ZeroResultType;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+ if (result_id == 0) {
|
|
|
|
+ TheStatus = Status::ZeroResultId;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ TheInst.reserve(4);
|
|
|
|
+ TheInst.emplace_back(
|
|
|
|
+ static_cast<uint32_t>(spv::Op::OpNamedBarrierInitialize));
|
|
|
|
+ TheInst.emplace_back(result_type);
|
|
|
|
+ TheInst.emplace_back(result_id);
|
|
|
|
+ TheInst.emplace_back(subgroup_count);
|
|
|
|
+
|
|
|
|
+ return *this;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+InstBuilder &InstBuilder::opMemoryNamedBarrier(uint32_t named_barrier,
|
|
|
|
+ uint32_t memory,
|
|
|
|
+ uint32_t semantics) {
|
|
|
|
+ if (!TheInst.empty()) {
|
|
|
|
+ TheStatus = Status::NestedInst;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ TheInst.reserve(4);
|
|
|
|
+ TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpMemoryNamedBarrier));
|
|
|
|
+ TheInst.emplace_back(named_barrier);
|
|
|
|
+ TheInst.emplace_back(memory);
|
|
|
|
+ TheInst.emplace_back(semantics);
|
|
|
|
+
|
|
|
|
+ return *this;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+InstBuilder &InstBuilder::opModuleProcessed(std::string process) {
|
|
|
|
+ if (!TheInst.empty()) {
|
|
|
|
+ TheStatus = Status::NestedInst;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ TheInst.reserve(2);
|
|
|
|
+ TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpModuleProcessed));
|
|
|
|
+ encodeString(process);
|
|
|
|
+
|
|
|
|
+ return *this;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+InstBuilder &InstBuilder::opExecutionModeId(uint32_t entry_point,
|
|
|
|
+ spv::ExecutionMode mode) {
|
|
|
|
+ if (!TheInst.empty()) {
|
|
|
|
+ TheStatus = Status::NestedInst;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ TheInst.reserve(3);
|
|
|
|
+ TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpExecutionModeId));
|
|
|
|
+ TheInst.emplace_back(entry_point);
|
|
|
|
+ encodeExecutionMode(mode);
|
|
|
|
+
|
|
|
|
+ return *this;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+InstBuilder &InstBuilder::opDecorateId(uint32_t target,
|
|
|
|
+ spv::Decoration decoration) {
|
|
|
|
+ if (!TheInst.empty()) {
|
|
|
|
+ TheStatus = Status::NestedInst;
|
|
|
|
+ return *this;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ TheInst.reserve(3);
|
|
|
|
+ TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpDecorateId));
|
|
|
|
+ TheInst.emplace_back(target);
|
|
|
|
+ encodeDecoration(decoration);
|
|
|
|
+
|
|
|
|
+ return *this;
|
|
|
|
+}
|
|
|
|
+
|
|
InstBuilder &InstBuilder::opSubgroupBallotKHR(uint32_t result_type,
|
|
InstBuilder &InstBuilder::opSubgroupBallotKHR(uint32_t result_type,
|
|
uint32_t result_id,
|
|
uint32_t result_id,
|
|
uint32_t predicate) {
|
|
uint32_t predicate) {
|
|
@@ -7831,6 +8094,13 @@ void InstBuilder::encodeImageOperands(spv::ImageOperandsMask value) {
|
|
TheInst.emplace_back(static_cast<uint32_t>(value));
|
|
TheInst.emplace_back(static_cast<uint32_t>(value));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void InstBuilder::encodeLoopControl(spv::LoopControlMask value) {
|
|
|
|
+ if (bitEnumContains(value, spv::LoopControlMask::DependencyLength)) {
|
|
|
|
+ Expectation.emplace_back(OperandKind::LiteralInteger);
|
|
|
|
+ }
|
|
|
|
+ TheInst.emplace_back(static_cast<uint32_t>(value));
|
|
|
|
+}
|
|
|
|
+
|
|
void InstBuilder::encodeMemoryAccess(spv::MemoryAccessMask value) {
|
|
void InstBuilder::encodeMemoryAccess(spv::MemoryAccessMask value) {
|
|
if (bitEnumContains(value, spv::MemoryAccessMask::Aligned)) {
|
|
if (bitEnumContains(value, spv::MemoryAccessMask::Aligned)) {
|
|
Expectation.emplace_back(OperandKind::LiteralInteger);
|
|
Expectation.emplace_back(OperandKind::LiteralInteger);
|
|
@@ -7859,6 +8129,23 @@ void InstBuilder::encodeExecutionMode(spv::ExecutionMode value) {
|
|
case spv::ExecutionMode::VecTypeHint: {
|
|
case spv::ExecutionMode::VecTypeHint: {
|
|
Expectation.emplace_back(OperandKind::LiteralInteger);
|
|
Expectation.emplace_back(OperandKind::LiteralInteger);
|
|
} break;
|
|
} break;
|
|
|
|
+ case spv::ExecutionMode::SubgroupSize: {
|
|
|
|
+ Expectation.emplace_back(OperandKind::LiteralInteger);
|
|
|
|
+ } break;
|
|
|
|
+ case spv::ExecutionMode::SubgroupsPerWorkgroup: {
|
|
|
|
+ Expectation.emplace_back(OperandKind::LiteralInteger);
|
|
|
|
+ } break;
|
|
|
|
+ case spv::ExecutionMode::SubgroupsPerWorkgroupId: {
|
|
|
|
+ Expectation.emplace_back(OperandKind::IdRef);
|
|
|
|
+ } break;
|
|
|
|
+ case spv::ExecutionMode::LocalSizeId: {
|
|
|
|
+ Expectation.emplace_back(OperandKind::IdRef);
|
|
|
|
+ Expectation.emplace_back(OperandKind::IdRef);
|
|
|
|
+ Expectation.emplace_back(OperandKind::IdRef);
|
|
|
|
+ } break;
|
|
|
|
+ case spv::ExecutionMode::LocalSizeHintId: {
|
|
|
|
+ Expectation.emplace_back(OperandKind::IdRef);
|
|
|
|
+ } break;
|
|
default:
|
|
default:
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -7926,6 +8213,15 @@ void InstBuilder::encodeDecoration(spv::Decoration value) {
|
|
case spv::Decoration::Alignment: {
|
|
case spv::Decoration::Alignment: {
|
|
Expectation.emplace_back(OperandKind::LiteralInteger);
|
|
Expectation.emplace_back(OperandKind::LiteralInteger);
|
|
} break;
|
|
} break;
|
|
|
|
+ case spv::Decoration::MaxByteOffset: {
|
|
|
|
+ Expectation.emplace_back(OperandKind::LiteralInteger);
|
|
|
|
+ } break;
|
|
|
|
+ case spv::Decoration::AlignmentId: {
|
|
|
|
+ Expectation.emplace_back(OperandKind::IdRef);
|
|
|
|
+ } break;
|
|
|
|
+ case spv::Decoration::MaxByteOffsetId: {
|
|
|
|
+ Expectation.emplace_back(OperandKind::IdRef);
|
|
|
|
+ } break;
|
|
case spv::Decoration::SecondaryViewportRelativeNV: {
|
|
case spv::Decoration::SecondaryViewportRelativeNV: {
|
|
Expectation.emplace_back(OperandKind::LiteralInteger);
|
|
Expectation.emplace_back(OperandKind::LiteralInteger);
|
|
} break;
|
|
} break;
|