mirror of
https://github.com/yuzu-emu/sirit.git
synced 2024-12-23 00:25:34 +00:00
Upgrade to C++20 and use std::span
This commit is contained in:
parent
eefca56afd
commit
c4ea8f4b76
|
@ -17,7 +17,7 @@ if (NOT CMAKE_BUILD_TYPE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Set hard requirements for C++
|
# Set hard requirements for C++
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
|
|
|
@ -6,13 +6,16 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <span>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <spirv/unified1/spirv.hpp11>
|
#include <spirv/unified1/spirv.hpp11>
|
||||||
|
|
||||||
namespace Sirit {
|
namespace Sirit {
|
||||||
|
@ -50,23 +53,25 @@ public:
|
||||||
|
|
||||||
/// Adds an entry point.
|
/// Adds an entry point.
|
||||||
void AddEntryPoint(spv::ExecutionModel execution_model, Id entry_point, std::string name,
|
void AddEntryPoint(spv::ExecutionModel execution_model, Id entry_point, std::string name,
|
||||||
const std::vector<Id>& interfaces = {});
|
std::span<const Id> interfaces = {});
|
||||||
|
|
||||||
/// Adds an entry point.
|
/// Adds an entry point.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
void AddEntryPoint(spv::ExecutionModel execution_model, Id entry_point, std::string name,
|
void AddEntryPoint(spv::ExecutionModel execution_model, Id entry_point, std::string name,
|
||||||
Ts&&... interfaces) {
|
Ts&&... interfaces) {
|
||||||
AddEntryPoint(execution_model, std::move(entry_point), name, {interfaces...});
|
AddEntryPoint(execution_model, std::move(entry_point), name,
|
||||||
|
std::span<const Id>{std::array{interfaces...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Declare an execution mode for an entry point.
|
/// Declare an execution mode for an entry point.
|
||||||
void AddExecutionMode(Id entry_point, spv::ExecutionMode mode,
|
void AddExecutionMode(Id entry_point, spv::ExecutionMode mode,
|
||||||
const std::vector<Literal>& literals = {});
|
std::span<const Literal> literals = {});
|
||||||
|
|
||||||
/// Declare an execution mode for an entry point.
|
/// Declare an execution mode for an entry point.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
void AddExecutionMode(Id entry_point, spv::ExecutionMode mode, Ts&&... literals) {
|
void AddExecutionMode(Id entry_point, spv::ExecutionMode mode, Ts&&... literals) {
|
||||||
AddExecutionMode(entry_point, mode, {literals...});
|
const Literal stack_literals[] = {std::forward<Ts>(literals)...};
|
||||||
|
AddExecutionMode(entry_point, mode, std::span<const Literal>{stack_literals});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -136,12 +141,12 @@ public:
|
||||||
Id TypeRuntimeArray(Id element_type);
|
Id TypeRuntimeArray(Id element_type);
|
||||||
|
|
||||||
/// Returns type struct.
|
/// Returns type struct.
|
||||||
Id TypeStruct(const std::vector<Id>& members = {});
|
Id TypeStruct(std::span<const Id> members = {});
|
||||||
|
|
||||||
/// Returns type struct.
|
/// Returns type struct.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id TypeStruct(Ts&&... members) {
|
Id TypeStruct(Ts&&... members) {
|
||||||
return TypeStruct({members...});
|
return TypeStruct(std::span<const Id>{std::array{members...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns type opaque.
|
/// Returns type opaque.
|
||||||
|
@ -151,12 +156,12 @@ public:
|
||||||
Id TypePointer(spv::StorageClass storage_class, Id type);
|
Id TypePointer(spv::StorageClass storage_class, Id type);
|
||||||
|
|
||||||
/// Returns type function.
|
/// Returns type function.
|
||||||
Id TypeFunction(Id return_type, const std::vector<Id>& arguments = {});
|
Id TypeFunction(Id return_type, std::span<const Id> arguments = {});
|
||||||
|
|
||||||
/// Returns type function.
|
/// Returns type function.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id TypeFunction(Id return_type, Ts&&... arguments) {
|
Id TypeFunction(Id return_type, Ts&&... arguments) {
|
||||||
return OpTypeFunction(return_type, {arguments...});
|
return TypeFunction(return_type, std::span<const Id>{std::array{arguments...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns type event.
|
/// Returns type event.
|
||||||
|
@ -186,12 +191,12 @@ public:
|
||||||
Id Constant(Id result_type, const Literal& literal);
|
Id Constant(Id result_type, const Literal& literal);
|
||||||
|
|
||||||
/// Returns a numeric scalar constant.
|
/// Returns a numeric scalar constant.
|
||||||
Id ConstantComposite(Id result_type, const std::vector<Id>& constituents);
|
Id ConstantComposite(Id result_type, std::span<const Id> constituents);
|
||||||
|
|
||||||
/// Returns a numeric scalar constant.
|
/// Returns a numeric scalar constant.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id ConstantComposite(Id result_type, Ts&&... constituents) {
|
Id ConstantComposite(Id result_type, Ts&&... constituents) {
|
||||||
return ConstantComposite(result_type, {constituents...});
|
return ConstantComposite(result_type, std::span<const Id>{std::array{constituents...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a sampler constant.
|
/// Returns a sampler constant.
|
||||||
|
@ -210,25 +215,26 @@ public:
|
||||||
Id OpFunctionEnd();
|
Id OpFunctionEnd();
|
||||||
|
|
||||||
/// Call a function.
|
/// Call a function.
|
||||||
Id OpFunctionCall(Id result_type, Id function, const std::vector<Id>& arguments = {});
|
Id OpFunctionCall(Id result_type, Id function, std::span<const Id> arguments = {});
|
||||||
|
|
||||||
/// Call a function.
|
/// Call a function.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id OpFunctionCall(Id result_type, Id function, Ts&&... arguments) {
|
Id OpFunctionCall(Id result_type, Id function, Ts&&... arguments) {
|
||||||
return OpFunctionCall(result_type, function, {arguments...});
|
return OpFunctionCall(result_type, function, std::span<const Id>{std::array{arguments...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flow
|
// Flow
|
||||||
|
|
||||||
/// Declare a structured loop.
|
/// Declare a structured loop.
|
||||||
Id OpLoopMerge(Id merge_block, Id continue_target, spv::LoopControlMask loop_control,
|
Id OpLoopMerge(Id merge_block, Id continue_target, spv::LoopControlMask loop_control,
|
||||||
const std::vector<Id>& literals = {});
|
std::span<const Id> literals = {});
|
||||||
|
|
||||||
/// Declare a structured loop.
|
/// Declare a structured loop.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id OpLoopMerge(Id merge_block, Id continue_target, spv::LoopControlMask loop_control,
|
Id OpLoopMerge(Id merge_block, Id continue_target, spv::LoopControlMask loop_control,
|
||||||
Ts&&... literals) {
|
Ts&&... literals) {
|
||||||
return OpLoopMerge(merge_block, continue_target, loop_control, {literals...});
|
return OpLoopMerge(merge_block, continue_target, loop_control,
|
||||||
|
std::span<const Id>{std::array{literals...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Declare a structured selection.
|
/// Declare a structured selection.
|
||||||
|
@ -251,8 +257,8 @@ public:
|
||||||
std::uint32_t true_weight = 0, std::uint32_t false_weight = 0);
|
std::uint32_t true_weight = 0, std::uint32_t false_weight = 0);
|
||||||
|
|
||||||
/// Multi-way branch to one of the operand label.
|
/// Multi-way branch to one of the operand label.
|
||||||
Id OpSwitch(Id selector, Id default_label, const std::vector<Literal>& literals,
|
Id OpSwitch(Id selector, Id default_label, std::span<const Literal> literals,
|
||||||
const std::vector<Id>& labels);
|
std::span<const Id> labels);
|
||||||
|
|
||||||
/// Returns with no value from a function with void return type.
|
/// Returns with no value from a function with void return type.
|
||||||
Id OpReturn();
|
Id OpReturn();
|
||||||
|
@ -284,7 +290,8 @@ public:
|
||||||
/// Allocate an object in memory, resulting in a copy to it.
|
/// Allocate an object in memory, resulting in a copy to it.
|
||||||
Id OpVariable(Id result_type, spv::StorageClass storage_class, Id initializer = nullptr);
|
Id OpVariable(Id result_type, spv::StorageClass storage_class, Id initializer = nullptr);
|
||||||
|
|
||||||
/// Form a pointer to a texel of an image. Use of such a pointer is limited to atomic operations.
|
/// Form a pointer to a texel of an image. Use of such a pointer is limited to atomic
|
||||||
|
/// operations.
|
||||||
Id OpImageTexelPointer(Id result_type, Id image, Id coordinate, Id sample);
|
Id OpImageTexelPointer(Id result_type, Id image, Id coordinate, Id sample);
|
||||||
|
|
||||||
/// Load through a pointer.
|
/// Load through a pointer.
|
||||||
|
@ -294,12 +301,12 @@ public:
|
||||||
Id OpStore(Id pointer, Id object, std::optional<spv::MemoryAccessMask> memory_access = {});
|
Id OpStore(Id pointer, Id object, std::optional<spv::MemoryAccessMask> memory_access = {});
|
||||||
|
|
||||||
/// Create a pointer into a composite object that can be used with OpLoad and OpStore.
|
/// Create a pointer into a composite object that can be used with OpLoad and OpStore.
|
||||||
Id OpAccessChain(Id result_type, Id base, const std::vector<Id>& indexes = {});
|
Id OpAccessChain(Id result_type, Id base, std::span<const Id> indexes = {});
|
||||||
|
|
||||||
/// Create a pointer into a composite object that can be used with OpLoad and OpStore.
|
/// Create a pointer into a composite object that can be used with OpLoad and OpStore.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id OpAccessChain(Id result_type, Id base, Ts&&... indexes) {
|
Id OpAccessChain(Id result_type, Id base, Ts&&... indexes) {
|
||||||
return OpAccessChain(result_type, base, {indexes...});
|
return OpAccessChain(result_type, base, std::span<const Id>{std::array{indexes...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract a single, dynamically selected, component of a vector.
|
/// Extract a single, dynamically selected, component of a vector.
|
||||||
|
@ -310,50 +317,56 @@ public:
|
||||||
|
|
||||||
/// Make a copy of a composite object, while modifying one part of it.
|
/// Make a copy of a composite object, while modifying one part of it.
|
||||||
Id OpCompositeInsert(Id result_type, Id object, Id composite,
|
Id OpCompositeInsert(Id result_type, Id object, Id composite,
|
||||||
const std::vector<Literal>& indexes = {});
|
std::span<const Literal> indexes = {});
|
||||||
|
|
||||||
/// Make a copy of a composite object, while modifying one part of it.
|
/// Make a copy of a composite object, while modifying one part of it.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id OpCompositeInsert(Id result_type, Id object, Id composite, Ts&&... indexes) {
|
Id OpCompositeInsert(Id result_type, Id object, Id composite, Ts&&... indexes) {
|
||||||
return OpCompositeInsert(result_type, object, composite, {indexes...});
|
const Literal stack_indexes[] = {std::forward<Ts>(indexes)...};
|
||||||
|
return OpCompositeInsert(result_type, object, composite,
|
||||||
|
std::span<const Literal>{stack_indexes});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract a part of a composite object.
|
/// Extract a part of a composite object.
|
||||||
Id OpCompositeExtract(Id result_type, Id composite, const std::vector<Literal>& indexes = {});
|
Id OpCompositeExtract(Id result_type, Id composite, std::span<const Literal> indexes = {});
|
||||||
|
|
||||||
/// Extract a part of a composite object.
|
/// Extract a part of a composite object.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id OpCompositeExtract(Id result_type, Id composite, Ts&&... indexes) {
|
Id OpCompositeExtract(Id result_type, Id composite, Ts&&... indexes) {
|
||||||
return OpCompositeExtract(result_type, composite, {indexes...});
|
const Literal stack_indexes[] = {std::forward<Ts>(indexes)...};
|
||||||
|
return OpCompositeExtract(result_type, composite, std::span<const Literal>{stack_indexes});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a new composite object from a set of constituent objects that will fully form it.
|
/// Construct a new composite object from a set of constituent objects that will fully form it.
|
||||||
Id OpCompositeConstruct(Id result_type, const std::vector<Id>& ids);
|
Id OpCompositeConstruct(Id result_type, std::span<const Id> ids);
|
||||||
|
|
||||||
/// Construct a new composite object from a set of constituent objects that will fully form it.
|
/// Construct a new composite object from a set of constituent objects that will fully form it.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id OpCompositeConstruct(Id result_type, Ts&&... ids) {
|
Id OpCompositeConstruct(Id result_type, Ts&&... ids) {
|
||||||
return OpCompositeConstruct(result_type, {ids...});
|
return OpCompositeConstruct(result_type, std::span<const Id>{std::array{ids...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Annotation
|
// Annotation
|
||||||
|
|
||||||
/// Add a decoration to target.
|
/// Add a decoration to target.
|
||||||
Id Decorate(Id target, spv::Decoration decoration, const std::vector<Literal>& literals = {});
|
Id Decorate(Id target, spv::Decoration decoration, std::span<const Literal> literals = {});
|
||||||
|
|
||||||
/// Add a decoration to target.
|
/// Add a decoration to target.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id Decorate(Id target, spv::Decoration decoration, Ts&&... literals) {
|
Id Decorate(Id target, spv::Decoration decoration, Ts&&... literals) {
|
||||||
return Decorate(target, decoration, {literals...});
|
const Literal stack_literals[] = {std::forward<Ts>(literals)...};
|
||||||
|
return Decorate(target, decoration, std::span<const Literal>{stack_literals});
|
||||||
}
|
}
|
||||||
|
|
||||||
Id MemberDecorate(Id structure_type, Literal member, spv::Decoration decoration,
|
Id MemberDecorate(Id structure_type, Literal member, spv::Decoration decoration,
|
||||||
const std::vector<Literal>& literals = {});
|
std::span<const Literal> literals = {});
|
||||||
|
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id MemberDecorate(Id structure_type, Literal member, spv::Decoration decoration,
|
Id MemberDecorate(Id structure_type, Literal member, spv::Decoration decoration,
|
||||||
Ts&&... literals) {
|
Ts&&... literals) {
|
||||||
return MemberDecorate(structure_type, member, decoration, {literals...});
|
const Literal stack_literals[] = {std::forward<Ts>(literals)...};
|
||||||
|
return MemberDecorate(structure_type, member, decoration,
|
||||||
|
std::span<const Literal>{stack_literals});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
|
@ -608,13 +621,13 @@ public:
|
||||||
// Extensions
|
// Extensions
|
||||||
|
|
||||||
/// Execute an instruction in an imported set of extended instructions.
|
/// Execute an instruction in an imported set of extended instructions.
|
||||||
Id OpExtInst(Id result_type, Id set, std::uint32_t instruction,
|
Id OpExtInst(Id result_type, Id set, std::uint32_t instruction, std::span<const Id> operands);
|
||||||
const std::vector<Id>& operands);
|
|
||||||
|
|
||||||
/// Execute an instruction in an imported set of extended instructions.
|
/// Execute an instruction in an imported set of extended instructions.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id OpExtInst(Id result_type, Id set, std::uint32_t instruction, Ts&&... operands) {
|
Id OpExtInst(Id result_type, Id set, std::uint32_t instruction, Ts&&... operands) {
|
||||||
return OpExtInst(result_type, set, instruction, {operands...});
|
return OpExtInst(result_type, set, instruction,
|
||||||
|
std::span<const Id>{std::array{operands...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Result is x if x >= 0; otherwise result is -x.
|
/// Result is x if x >= 0; otherwise result is -x.
|
||||||
|
@ -764,86 +777,88 @@ public:
|
||||||
/// Sample an image with an implicit level of detail.
|
/// Sample an image with an implicit level of detail.
|
||||||
Id OpImageSampleImplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
Id OpImageSampleImplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
||||||
std::optional<spv::ImageOperandsMask> image_operands = {},
|
std::optional<spv::ImageOperandsMask> image_operands = {},
|
||||||
const std::vector<Id>& operands = {});
|
std::span<const Id> operands = {});
|
||||||
|
|
||||||
/// Sample an image with an implicit level of detail.
|
/// Sample an image with an implicit level of detail.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id OpImageSampleImplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
Id OpImageSampleImplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
||||||
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
||||||
return OpImageSampleImplicitLod(result_type, sampled_image, coordinate, image_operands,
|
return OpImageSampleImplicitLod(result_type, sampled_image, coordinate, image_operands,
|
||||||
{operands...});
|
std::span<const Id>{std::array{operands...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sample an image using an explicit level of detail.
|
/// Sample an image using an explicit level of detail.
|
||||||
Id OpImageSampleExplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
Id OpImageSampleExplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
||||||
spv::ImageOperandsMask image_operands,
|
spv::ImageOperandsMask image_operands,
|
||||||
const std::vector<Id>& operands = {});
|
std::span<const Id> operands = {});
|
||||||
|
|
||||||
/// Sample an image using an explicit level of detail.
|
/// Sample an image using an explicit level of detail.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id OpImageSampleExplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
Id OpImageSampleExplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
||||||
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
||||||
return OpImageSampleExplicitLod(result_type, sampled_image, coordinate, image_operands,
|
return OpImageSampleExplicitLod(result_type, sampled_image, coordinate, image_operands,
|
||||||
{operands...});
|
std::span<const Id>{std::array{operands...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sample an image doing depth-comparison with an implicit level of detail.
|
/// Sample an image doing depth-comparison with an implicit level of detail.
|
||||||
Id OpImageSampleDrefImplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
Id OpImageSampleDrefImplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
||||||
std::optional<spv::ImageOperandsMask> image_operands = {},
|
std::optional<spv::ImageOperandsMask> image_operands = {},
|
||||||
const std::vector<Id>& operands = {});
|
std::span<const Id> operands = {});
|
||||||
|
|
||||||
/// Sample an image doing depth-comparison with an implicit level of detail.
|
/// Sample an image doing depth-comparison with an implicit level of detail.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id OpImageSampleDrefImplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
Id OpImageSampleDrefImplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
||||||
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
||||||
return OpImageSampleDrefImplicitLod(result_type, sampled_image, coordinate, dref,
|
return OpImageSampleDrefImplicitLod(result_type, sampled_image, coordinate, dref,
|
||||||
image_operands, {operands...});
|
image_operands,
|
||||||
|
std::span<const Id>{std::array{operands...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sample an image doing depth-comparison using an explicit level of detail.
|
/// Sample an image doing depth-comparison using an explicit level of detail.
|
||||||
Id OpImageSampleDrefExplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
Id OpImageSampleDrefExplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
||||||
spv::ImageOperandsMask image_operands,
|
spv::ImageOperandsMask image_operands,
|
||||||
const std::vector<Id>& operands = {});
|
std::span<const Id> operands = {});
|
||||||
|
|
||||||
/// Sample an image doing depth-comparison using an explicit level of detail.
|
/// Sample an image doing depth-comparison using an explicit level of detail.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id OpImageSampleDrefExplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
Id OpImageSampleDrefExplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
||||||
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
||||||
return OpImageSampleDrefExplicitLod(result_type, sampled_image, coordinate, dref,
|
return OpImageSampleDrefExplicitLod(result_type, sampled_image, coordinate, dref,
|
||||||
image_operands, {operands...});
|
image_operands,
|
||||||
|
std::span<const Id>{std::array{operands...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sample an image with with a project coordinate and an implicit level of detail.
|
/// Sample an image with with a project coordinate and an implicit level of detail.
|
||||||
Id OpImageSampleProjImplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
Id OpImageSampleProjImplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
||||||
std::optional<spv::ImageOperandsMask> image_operands = {},
|
std::optional<spv::ImageOperandsMask> image_operands = {},
|
||||||
const std::vector<Id>& operands = {});
|
std::span<const Id> operands = {});
|
||||||
|
|
||||||
/// Sample an image with with a project coordinate and an implicit level of detail.
|
/// Sample an image with with a project coordinate and an implicit level of detail.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id OpImageSampleProjImplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
Id OpImageSampleProjImplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
||||||
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
||||||
return OpImageSampleProjImplicitLod(result_type, sampled_image, coordinate, image_operands,
|
return OpImageSampleProjImplicitLod(result_type, sampled_image, coordinate, image_operands,
|
||||||
{operands...});
|
std::span<const Id>{std::array{operands...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sample an image with a project coordinate using an explicit level of detail.
|
/// Sample an image with a project coordinate using an explicit level of detail.
|
||||||
Id OpImageSampleProjExplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
Id OpImageSampleProjExplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
||||||
spv::ImageOperandsMask image_operands,
|
spv::ImageOperandsMask image_operands,
|
||||||
const std::vector<Id>& operands = {});
|
std::span<const Id> operands = {});
|
||||||
|
|
||||||
/// Sample an image with a project coordinate using an explicit level of detail.
|
/// Sample an image with a project coordinate using an explicit level of detail.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id OpImageSampleProjExplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
Id OpImageSampleProjExplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
||||||
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
||||||
return OpImageSampleProjExplicitLod(result_type, sampled_image, coordinate, image_operands,
|
return OpImageSampleProjExplicitLod(result_type, sampled_image, coordinate, image_operands,
|
||||||
{operands...});
|
std::span<const Id>{std::array{operands...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sample an image with a project coordinate, doing depth-comparison, with an implicit level of
|
/// Sample an image with a project coordinate, doing depth-comparison, with an implicit level of
|
||||||
/// detail.
|
/// detail.
|
||||||
Id OpImageSampleProjDrefImplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
Id OpImageSampleProjDrefImplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
||||||
std::optional<spv::ImageOperandsMask> image_operands = {},
|
std::optional<spv::ImageOperandsMask> image_operands = {},
|
||||||
const std::vector<Id>& operands = {});
|
std::span<const Id> operands = {});
|
||||||
|
|
||||||
/// Sample an image with a project coordinate, doing depth-comparison, with an implicit level of
|
/// Sample an image with a project coordinate, doing depth-comparison, with an implicit level of
|
||||||
/// detail.
|
/// detail.
|
||||||
|
@ -851,14 +866,15 @@ public:
|
||||||
Id OpImageSampleProjDrefImplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
Id OpImageSampleProjDrefImplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
||||||
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
||||||
return OpImageSampleProjDrefImplicitLod(result_type, sampled_image, coordinate, dref,
|
return OpImageSampleProjDrefImplicitLod(result_type, sampled_image, coordinate, dref,
|
||||||
image_operands, {operands...});
|
image_operands,
|
||||||
|
std::span<const Id>{std::array{operands...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sample an image with a project coordinate, doing depth-comparison, using an explicit level
|
/// Sample an image with a project coordinate, doing depth-comparison, using an explicit level
|
||||||
/// of detail.
|
/// of detail.
|
||||||
Id OpImageSampleProjDrefExplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
Id OpImageSampleProjDrefExplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
||||||
spv::ImageOperandsMask image_operands,
|
spv::ImageOperandsMask image_operands,
|
||||||
const std::vector<Id>& operands = {});
|
std::span<const Id> operands = {});
|
||||||
|
|
||||||
/// Sample an image with a project coordinate, doing depth-comparison, using an explicit level
|
/// Sample an image with a project coordinate, doing depth-comparison, using an explicit level
|
||||||
/// of detail.
|
/// of detail.
|
||||||
|
@ -866,69 +882,73 @@ public:
|
||||||
Id OpImageSampleProjDrefExplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
Id OpImageSampleProjDrefExplicitLod(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
||||||
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
||||||
return OpImageSampleProjDrefExplicitLod(result_type, sampled_image, coordinate, dref,
|
return OpImageSampleProjDrefExplicitLod(result_type, sampled_image, coordinate, dref,
|
||||||
image_operands, {operands...});
|
image_operands,
|
||||||
|
std::span<const Id>{std::array{operands...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch a single texel from an image whose Sampled operand is 1.
|
/// Fetch a single texel from an image whose Sampled operand is 1.
|
||||||
Id OpImageFetch(Id result_type, Id sampled_image, Id coordinate,
|
Id OpImageFetch(Id result_type, Id sampled_image, Id coordinate,
|
||||||
std::optional<spv::ImageOperandsMask> image_operands = {},
|
std::optional<spv::ImageOperandsMask> image_operands = {},
|
||||||
const std::vector<Id>& operands = {});
|
std::span<const Id> operands = {});
|
||||||
|
|
||||||
/// Fetch a single texel from an image whose Sampled operand is 1.
|
/// Fetch a single texel from an image whose Sampled operand is 1.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id OpImageFetch(Id result_type, Id sampled_image, Id coordinate,
|
Id OpImageFetch(Id result_type, Id sampled_image, Id coordinate,
|
||||||
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
||||||
return OpImageFetch(result_type, sampled_image, coordinate, image_operands, {operands...});
|
return OpImageFetch(result_type, sampled_image, coordinate, image_operands,
|
||||||
|
std::span<const Id>{std::array{operands...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gathers the requested component from four texels.
|
/// Gathers the requested component from four texels.
|
||||||
Id OpImageGather(Id result_type, Id sampled_image, Id coordinate, Id component,
|
Id OpImageGather(Id result_type, Id sampled_image, Id coordinate, Id component,
|
||||||
std::optional<spv::ImageOperandsMask> image_operands = {},
|
std::optional<spv::ImageOperandsMask> image_operands = {},
|
||||||
const std::vector<Id>& operands = {});
|
std::span<const Id> operands = {});
|
||||||
|
|
||||||
/// Gathers the requested component from four texels.
|
/// Gathers the requested component from four texels.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id OpImageGather(Id result_type, Id sampled_image, Id coordinate, Id component,
|
Id OpImageGather(Id result_type, Id sampled_image, Id coordinate, Id component,
|
||||||
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
||||||
return OpImageGather(result_type, sampled_image, coordinate, component, image_operands,
|
return OpImageGather(result_type, sampled_image, coordinate, component, image_operands,
|
||||||
{operands...});
|
std::span<const Id>{std::array{operands...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gathers the requested depth-comparison from four texels.
|
/// Gathers the requested depth-comparison from four texels.
|
||||||
Id OpImageDrefGather(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
Id OpImageDrefGather(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
||||||
std::optional<spv::ImageOperandsMask> image_operands = {},
|
std::optional<spv::ImageOperandsMask> image_operands = {},
|
||||||
const std::vector<Id>& operands = {});
|
std::span<const Id> operands = {});
|
||||||
|
|
||||||
/// Gathers the requested depth-comparison from four texels.
|
/// Gathers the requested depth-comparison from four texels.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id OpImageDrefGather(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
Id OpImageDrefGather(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
||||||
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
||||||
return OpImageDrefGather(result_type, sampled_image, coordinate, dref, image_operands,
|
return OpImageDrefGather(result_type, sampled_image, coordinate, dref, image_operands,
|
||||||
{operands...});
|
std::span<const Id>{std::array{operands...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read a texel from an image without a sampler.
|
/// Read a texel from an image without a sampler.
|
||||||
Id OpImageRead(Id result_type, Id sampled_image, Id coordinate,
|
Id OpImageRead(Id result_type, Id sampled_image, Id coordinate,
|
||||||
std::optional<spv::ImageOperandsMask> image_operands = {},
|
std::optional<spv::ImageOperandsMask> image_operands = {},
|
||||||
const std::vector<Id>& operands = {});
|
std::span<const Id> operands = {});
|
||||||
|
|
||||||
/// Read a texel from an image without a sampler.
|
/// Read a texel from an image without a sampler.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id OpImageRead(Id result_type, Id sampled_image, Id coordinate,
|
Id OpImageRead(Id result_type, Id sampled_image, Id coordinate,
|
||||||
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
spv::ImageOperandsMask image_operands, Ts&&... operands) {
|
||||||
return OpImageRead(result_type, sampled_image, coordinate, image_operands, {operands...});
|
return OpImageRead(result_type, sampled_image, coordinate, image_operands,
|
||||||
|
std::span<const Id>{std::array{operands...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write a texel to an image without a sampler.
|
/// Write a texel to an image without a sampler.
|
||||||
Id OpImageWrite(Id image, Id coordinate, Id texel,
|
Id OpImageWrite(Id image, Id coordinate, Id texel,
|
||||||
std::optional<spv::ImageOperandsMask> image_operands = {},
|
std::optional<spv::ImageOperandsMask> image_operands = {},
|
||||||
const std::vector<Id>& operands = {});
|
std::span<const Id> operands = {});
|
||||||
|
|
||||||
/// Write a texel to an image without a sampler.
|
/// Write a texel to an image without a sampler.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
Id OpImageWrite(Id image, Id coordinate, Id texel, spv::ImageOperandsMask image_operands,
|
Id OpImageWrite(Id image, Id coordinate, Id texel, spv::ImageOperandsMask image_operands,
|
||||||
Ts&&... operands) {
|
Ts&&... operands) {
|
||||||
return OpImageWrite(image, coordinate, texel, image_operands, {operands...});
|
return OpImageWrite(image, coordinate, texel, image_operands,
|
||||||
|
std::span<const Id>{std::array{operands...}});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the image from a sampled image.
|
/// Extract the image from a sampled image.
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
namespace Sirit {
|
namespace Sirit {
|
||||||
|
|
||||||
Id Module::Decorate(Id target, spv::Decoration decoration, const std::vector<Literal>& literals) {
|
Id Module::Decorate(Id target, spv::Decoration decoration, std::span<const Literal> literals) {
|
||||||
auto op{std::make_unique<Op>(spv::Op::OpDecorate)};
|
auto op{std::make_unique<Op>(spv::Op::OpDecorate)};
|
||||||
op->Add(target);
|
op->Add(target);
|
||||||
op->Add(static_cast<u32>(decoration));
|
op->Add(static_cast<u32>(decoration));
|
||||||
|
@ -22,7 +22,7 @@ Id Module::Decorate(Id target, spv::Decoration decoration, const std::vector<Lit
|
||||||
}
|
}
|
||||||
|
|
||||||
Id Module::MemberDecorate(Id structure_type, Literal member, spv::Decoration decoration,
|
Id Module::MemberDecorate(Id structure_type, Literal member, spv::Decoration decoration,
|
||||||
const std::vector<Literal>& literals) {
|
std::span<const Literal> literals) {
|
||||||
auto op{std::make_unique<Op>(spv::Op::OpMemberDecorate)};
|
auto op{std::make_unique<Op>(spv::Op::OpMemberDecorate)};
|
||||||
op->Add(structure_type);
|
op->Add(structure_type);
|
||||||
op->Add(member);
|
op->Add(member);
|
||||||
|
|
|
@ -24,7 +24,7 @@ Id Module::Constant(Id result_type, const Literal& literal) {
|
||||||
return AddDeclaration(std::move(op));
|
return AddDeclaration(std::move(op));
|
||||||
}
|
}
|
||||||
|
|
||||||
Id Module::ConstantComposite(Id result_type, const std::vector<Id>& constituents) {
|
Id Module::ConstantComposite(Id result_type, std::span<const Id> constituents) {
|
||||||
auto op{std::make_unique<Op>(spv::Op::OpConstantComposite, bound, result_type)};
|
auto op{std::make_unique<Op>(spv::Op::OpConstantComposite, bound, result_type)};
|
||||||
op->Add(constituents);
|
op->Add(constituents);
|
||||||
return AddDeclaration(std::move(op));
|
return AddDeclaration(std::move(op));
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
namespace Sirit {
|
namespace Sirit {
|
||||||
|
|
||||||
Id Module::OpExtInst(Id result_type, Id set, u32 instruction, const std::vector<Id>& operands) {
|
Id Module::OpExtInst(Id result_type, Id set, u32 instruction, std::span<const Id> operands) {
|
||||||
auto op{std::make_unique<Op>(spv::Op::OpExtInst, bound++, result_type)};
|
auto op{std::make_unique<Op>(spv::Op::OpExtInst, bound++, result_type)};
|
||||||
op->Add(set);
|
op->Add(set);
|
||||||
op->Add(instruction);
|
op->Add(instruction);
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
namespace Sirit {
|
namespace Sirit {
|
||||||
|
|
||||||
Id Module::OpLoopMerge(Id merge_block, Id continue_target, spv::LoopControlMask loop_control,
|
Id Module::OpLoopMerge(Id merge_block, Id continue_target, spv::LoopControlMask loop_control,
|
||||||
const std::vector<Id>& literals) {
|
std::span<const Id> literals) {
|
||||||
auto op{std::make_unique<Op>(spv::Op::OpLoopMerge)};
|
auto op{std::make_unique<Op>(spv::Op::OpLoopMerge)};
|
||||||
op->Add(merge_block);
|
op->Add(merge_block);
|
||||||
op->Add(continue_target);
|
op->Add(continue_target);
|
||||||
|
@ -52,8 +52,8 @@ Id Module::OpBranchConditional(Id condition, Id true_label, Id false_label, u32
|
||||||
return AddCode(std::move(op));
|
return AddCode(std::move(op));
|
||||||
}
|
}
|
||||||
|
|
||||||
Id Module::OpSwitch(Id selector, Id default_label, const std::vector<Literal>& literals,
|
Id Module::OpSwitch(Id selector, Id default_label, std::span<const Literal> literals,
|
||||||
const std::vector<Id>& labels) {
|
std::span<const Id> labels) {
|
||||||
const std::size_t size = literals.size();
|
const std::size_t size = literals.size();
|
||||||
assert(literals.size() == labels.size());
|
assert(literals.size() == labels.size());
|
||||||
auto op{std::make_unique<Op>(spv::Op::OpSwitch)};
|
auto op{std::make_unique<Op>(spv::Op::OpSwitch)};
|
||||||
|
|
|
@ -21,7 +21,7 @@ Id Module::OpFunctionEnd() {
|
||||||
return AddCode(spv::Op::OpFunctionEnd);
|
return AddCode(spv::Op::OpFunctionEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
Id Module::OpFunctionCall(Id result_type, Id function, const std::vector<Id>& arguments) {
|
Id Module::OpFunctionCall(Id result_type, Id function, std::span<const Id> arguments) {
|
||||||
auto op{std::make_unique<Op>(spv::Op::OpFunctionCall, bound++, result_type)};
|
auto op{std::make_unique<Op>(spv::Op::OpFunctionCall, bound++, result_type)};
|
||||||
op->Add(function);
|
op->Add(function);
|
||||||
op->Add(arguments);
|
op->Add(arguments);
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
namespace Sirit {
|
namespace Sirit {
|
||||||
|
|
||||||
static void AddImageOperands(Op* op, std::optional<spv::ImageOperandsMask> image_operands,
|
static void AddImageOperands(Op* op, std::optional<spv::ImageOperandsMask> image_operands,
|
||||||
const std::vector<Id>& operands) {
|
std::span<const Id> operands) {
|
||||||
if (!image_operands)
|
if (!image_operands)
|
||||||
return;
|
return;
|
||||||
op->Add(static_cast<u32>(*image_operands));
|
op->Add(static_cast<u32>(*image_operands));
|
||||||
|
@ -21,7 +21,7 @@ static void AddImageOperands(Op* op, std::optional<spv::ImageOperandsMask> image
|
||||||
#define DEFINE_IMAGE_OP(opcode) \
|
#define DEFINE_IMAGE_OP(opcode) \
|
||||||
Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, \
|
Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, \
|
||||||
std::optional<spv::ImageOperandsMask> image_operands, \
|
std::optional<spv::ImageOperandsMask> image_operands, \
|
||||||
const std::vector<Id>& operands) { \
|
std::span<const Id> operands) { \
|
||||||
auto op{std::make_unique<Op>(spv::Op::opcode, bound++, result_type)}; \
|
auto op{std::make_unique<Op>(spv::Op::opcode, bound++, result_type)}; \
|
||||||
op->Add(sampled_image); \
|
op->Add(sampled_image); \
|
||||||
op->Add(coordinate); \
|
op->Add(coordinate); \
|
||||||
|
@ -31,7 +31,7 @@ static void AddImageOperands(Op* op, std::optional<spv::ImageOperandsMask> image
|
||||||
|
|
||||||
#define DEFINE_IMAGE_EXP_OP(opcode) \
|
#define DEFINE_IMAGE_EXP_OP(opcode) \
|
||||||
Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, \
|
Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, \
|
||||||
spv::ImageOperandsMask image_operands, const std::vector<Id>& operands) { \
|
spv::ImageOperandsMask image_operands, std::span<const Id> operands) { \
|
||||||
auto op{std::make_unique<Op>(spv::Op::opcode, bound++, result_type)}; \
|
auto op{std::make_unique<Op>(spv::Op::opcode, bound++, result_type)}; \
|
||||||
op->Add(sampled_image); \
|
op->Add(sampled_image); \
|
||||||
op->Add(coordinate); \
|
op->Add(coordinate); \
|
||||||
|
@ -43,7 +43,7 @@ static void AddImageOperands(Op* op, std::optional<spv::ImageOperandsMask> image
|
||||||
#define DEFINE_IMAGE_EXTRA_OP(opcode) \
|
#define DEFINE_IMAGE_EXTRA_OP(opcode) \
|
||||||
Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, Id extra, \
|
Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, Id extra, \
|
||||||
std::optional<spv::ImageOperandsMask> image_operands, \
|
std::optional<spv::ImageOperandsMask> image_operands, \
|
||||||
const std::vector<Id>& operands) { \
|
std::span<const Id> operands) { \
|
||||||
auto op{std::make_unique<Op>(spv::Op::opcode, bound++, result_type)}; \
|
auto op{std::make_unique<Op>(spv::Op::opcode, bound++, result_type)}; \
|
||||||
op->Add(sampled_image); \
|
op->Add(sampled_image); \
|
||||||
op->Add(coordinate); \
|
op->Add(coordinate); \
|
||||||
|
@ -54,7 +54,7 @@ static void AddImageOperands(Op* op, std::optional<spv::ImageOperandsMask> image
|
||||||
|
|
||||||
#define DEFINE_IMAGE_EXTRA_EXP_OP(opcode) \
|
#define DEFINE_IMAGE_EXTRA_EXP_OP(opcode) \
|
||||||
Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, Id extra, \
|
Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, Id extra, \
|
||||||
spv::ImageOperandsMask image_operands, const std::vector<Id>& operands) { \
|
spv::ImageOperandsMask image_operands, std::span<const Id> operands) { \
|
||||||
auto op{std::make_unique<Op>(spv::Op::opcode, bound++, result_type)}; \
|
auto op{std::make_unique<Op>(spv::Op::opcode, bound++, result_type)}; \
|
||||||
op->Add(sampled_image); \
|
op->Add(sampled_image); \
|
||||||
op->Add(coordinate); \
|
op->Add(coordinate); \
|
||||||
|
@ -106,7 +106,7 @@ Id Module::OpSampledImage(Id result_type, Id image, Id sampler) {
|
||||||
|
|
||||||
Id Module::OpImageWrite(Id image, Id coordinate, Id texel,
|
Id Module::OpImageWrite(Id image, Id coordinate, Id texel,
|
||||||
std::optional<spv::ImageOperandsMask> image_operands,
|
std::optional<spv::ImageOperandsMask> image_operands,
|
||||||
const std::vector<Id>& operands) {
|
std::span<const Id> operands) {
|
||||||
auto op{std::make_unique<Op>(spv::Op::OpImageWrite)};
|
auto op{std::make_unique<Op>(spv::Op::OpImageWrite)};
|
||||||
op->Add(image);
|
op->Add(image);
|
||||||
op->Add(coordinate);
|
op->Add(coordinate);
|
||||||
|
|
|
@ -46,7 +46,7 @@ Id Module::OpStore(Id pointer, Id object, std::optional<spv::MemoryAccessMask> m
|
||||||
return AddCode(std::move(op));
|
return AddCode(std::move(op));
|
||||||
}
|
}
|
||||||
|
|
||||||
Id Module::OpAccessChain(Id result_type, Id base, const std::vector<Id>& indexes) {
|
Id Module::OpAccessChain(Id result_type, Id base, std::span<const Id> indexes) {
|
||||||
assert(indexes.size() > 0);
|
assert(indexes.size() > 0);
|
||||||
auto op{std::make_unique<Op>(spv::Op::OpAccessChain, bound++, result_type)};
|
auto op{std::make_unique<Op>(spv::Op::OpAccessChain, bound++, result_type)};
|
||||||
op->Add(base);
|
op->Add(base);
|
||||||
|
@ -70,7 +70,7 @@ Id Module::OpVectorInsertDynamic(Id result_type, Id vector, Id component, Id ind
|
||||||
}
|
}
|
||||||
|
|
||||||
Id Module::OpCompositeInsert(Id result_type, Id object, Id composite,
|
Id Module::OpCompositeInsert(Id result_type, Id object, Id composite,
|
||||||
const std::vector<Literal>& indexes) {
|
std::span<const Literal> indexes) {
|
||||||
auto op{std::make_unique<Op>(spv::Op::OpCompositeInsert, bound++, result_type)};
|
auto op{std::make_unique<Op>(spv::Op::OpCompositeInsert, bound++, result_type)};
|
||||||
op->Add(object);
|
op->Add(object);
|
||||||
op->Add(composite);
|
op->Add(composite);
|
||||||
|
@ -78,14 +78,14 @@ Id Module::OpCompositeInsert(Id result_type, Id object, Id composite,
|
||||||
return AddCode(std::move(op));
|
return AddCode(std::move(op));
|
||||||
}
|
}
|
||||||
|
|
||||||
Id Module::OpCompositeExtract(Id result_type, Id composite, const std::vector<Literal>& indexes) {
|
Id Module::OpCompositeExtract(Id result_type, Id composite, std::span<const Literal> indexes) {
|
||||||
auto op{std::make_unique<Op>(spv::Op::OpCompositeExtract, bound++, result_type)};
|
auto op{std::make_unique<Op>(spv::Op::OpCompositeExtract, bound++, result_type)};
|
||||||
op->Add(composite);
|
op->Add(composite);
|
||||||
op->Add(indexes);
|
op->Add(indexes);
|
||||||
return AddCode(std::move(op));
|
return AddCode(std::move(op));
|
||||||
}
|
}
|
||||||
|
|
||||||
Id Module::OpCompositeConstruct(Id result_type, const std::vector<Id>& ids) {
|
Id Module::OpCompositeConstruct(Id result_type, std::span<const Id> ids) {
|
||||||
assert(ids.size() >= 1);
|
assert(ids.size() >= 1);
|
||||||
auto op{std::make_unique<Op>(spv::Op::OpCompositeConstruct, bound++, result_type)};
|
auto op{std::make_unique<Op>(spv::Op::OpCompositeConstruct, bound++, result_type)};
|
||||||
op->Add(ids);
|
op->Add(ids);
|
||||||
|
|
|
@ -90,7 +90,7 @@ Id Module::TypeRuntimeArray(Id element_type) {
|
||||||
return AddDeclaration(std::move(op));
|
return AddDeclaration(std::move(op));
|
||||||
}
|
}
|
||||||
|
|
||||||
Id Module::TypeStruct(const std::vector<Id>& members) {
|
Id Module::TypeStruct(std::span<const Id> members) {
|
||||||
auto op{std::make_unique<Op>(spv::Op::OpTypeStruct, bound)};
|
auto op{std::make_unique<Op>(spv::Op::OpTypeStruct, bound)};
|
||||||
op->Add(members);
|
op->Add(members);
|
||||||
return AddDeclaration(std::move(op));
|
return AddDeclaration(std::move(op));
|
||||||
|
@ -109,7 +109,7 @@ Id Module::TypePointer(spv::StorageClass storage_class, Id type) {
|
||||||
return AddDeclaration(std::move(op));
|
return AddDeclaration(std::move(op));
|
||||||
}
|
}
|
||||||
|
|
||||||
Id Module::TypeFunction(Id return_type, const std::vector<Id>& arguments) {
|
Id Module::TypeFunction(Id return_type, std::span<const Id> arguments) {
|
||||||
auto op{std::make_unique<Op>(spv::Op::OpTypeFunction, bound)};
|
auto op{std::make_unique<Op>(spv::Op::OpTypeFunction, bound)};
|
||||||
op->Add(return_type);
|
op->Add(return_type);
|
||||||
op->Add(arguments);
|
op->Add(arguments);
|
||||||
|
|
|
@ -26,7 +26,7 @@ std::size_t LiteralNumber::GetWordCount() const noexcept {
|
||||||
return is_32 ? 1 : 2;
|
return is_32 ? 1 : 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LiteralNumber::operator==(const Operand& other) const noexcept {
|
bool LiteralNumber::Equal(const Operand& other) const noexcept {
|
||||||
if (!EqualType(other)) {
|
if (!EqualType(other)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ public:
|
||||||
|
|
||||||
std::size_t GetWordCount() const noexcept override;
|
std::size_t GetWordCount() const noexcept override;
|
||||||
|
|
||||||
bool operator==(const Operand& other) const noexcept override;
|
bool Equal(const Operand& other) const noexcept override;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static std::unique_ptr<LiteralNumber> Create(T value) {
|
static std::unique_ptr<LiteralNumber> Create(T value) {
|
||||||
|
|
|
@ -23,7 +23,7 @@ std::size_t LiteralString::GetWordCount() const noexcept {
|
||||||
return string.size() / 4 + 1;
|
return string.size() / 4 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LiteralString::operator==(const Operand& other) const noexcept {
|
bool LiteralString::Equal(const Operand& other) const noexcept {
|
||||||
if (!EqualType(other)) {
|
if (!EqualType(other)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ public:
|
||||||
|
|
||||||
std::size_t GetWordCount() const noexcept override;
|
std::size_t GetWordCount() const noexcept override;
|
||||||
|
|
||||||
bool operator==(const Operand& other) const noexcept override;
|
bool Equal(const Operand& other) const noexcept override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string string;
|
std::string string;
|
||||||
|
|
|
@ -30,7 +30,7 @@ std::size_t Op::GetWordCount() const noexcept {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Op::operator==(const Operand& other) const noexcept {
|
bool Op::Equal(const Operand& other) const noexcept {
|
||||||
if (!EqualType(other)) {
|
if (!EqualType(other)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ bool Op::operator==(const Operand& other) const noexcept {
|
||||||
if (op.opcode == opcode && result_type == op.result_type &&
|
if (op.opcode == opcode && result_type == op.result_type &&
|
||||||
operands.size() == op.operands.size()) {
|
operands.size() == op.operands.size()) {
|
||||||
for (std::size_t i = 0; i < operands.size(); i++) {
|
for (std::size_t i = 0; i < operands.size(); i++) {
|
||||||
if (*operands[i] != *op.operands[i]) {
|
if (!operands[i]->Equal(*op.operands[i])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ void Op::Add(const Literal& literal) {
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Op::Add(const std::vector<Literal>& literals) {
|
void Op::Add(std::span<const Literal> literals) {
|
||||||
for (const auto& literal : literals) {
|
for (const auto& literal : literals) {
|
||||||
Add(literal);
|
Add(literal);
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ void Op::Add(std::string string) {
|
||||||
Sink(std::make_unique<LiteralString>(std::move(string)));
|
Sink(std::make_unique<LiteralString>(std::move(string)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Op::Add(const std::vector<Id>& ids) {
|
void Op::Add(std::span<const Id> ids) {
|
||||||
assert(std::all_of(ids.begin(), ids.end(), [](auto id_) { return id_; }));
|
assert(std::all_of(ids.begin(), ids.end(), [](auto id_) { return id_; }));
|
||||||
operands.insert(operands.end(), ids.begin(), ids.end());
|
operands.insert(operands.end(), ids.begin(), ids.end());
|
||||||
}
|
}
|
||||||
|
|
6
src/op.h
6
src/op.h
|
@ -26,7 +26,7 @@ public:
|
||||||
|
|
||||||
std::size_t GetWordCount() const noexcept override;
|
std::size_t GetWordCount() const noexcept override;
|
||||||
|
|
||||||
bool operator==(const Operand& other) const noexcept override;
|
bool Equal(const Operand& other) const noexcept override;
|
||||||
|
|
||||||
void Write(Stream& stream) const;
|
void Write(Stream& stream) const;
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ public:
|
||||||
|
|
||||||
void Add(const Literal& literal);
|
void Add(const Literal& literal);
|
||||||
|
|
||||||
void Add(const std::vector<Literal>& literals);
|
void Add(std::span<const Literal> literals);
|
||||||
|
|
||||||
void Add(const Operand* operand);
|
void Add(const Operand* operand);
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ public:
|
||||||
|
|
||||||
void Add(std::string string);
|
void Add(std::string string);
|
||||||
|
|
||||||
void Add(const std::vector<Id>& ids);
|
void Add(std::span<const Id> ids);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u16 CalculateTotalWords() const noexcept;
|
u16 CalculateTotalWords() const noexcept;
|
||||||
|
|
|
@ -23,11 +23,7 @@ public:
|
||||||
|
|
||||||
virtual std::size_t GetWordCount() const noexcept = 0;
|
virtual std::size_t GetWordCount() const noexcept = 0;
|
||||||
|
|
||||||
virtual bool operator==(const Operand& other) const noexcept = 0;
|
virtual bool Equal(const Operand& other) const noexcept = 0;
|
||||||
|
|
||||||
bool operator!=(const Operand& other) const noexcept {
|
|
||||||
return !operator==(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EqualType(const Operand& other) const noexcept {
|
bool EqualType(const Operand& other) const noexcept {
|
||||||
return operand_type == other.operand_type;
|
return operand_type == other.operand_type;
|
||||||
|
|
|
@ -74,13 +74,14 @@ void Module::AddCapability(spv::Capability capability) {
|
||||||
capabilities.insert(capability);
|
capabilities.insert(capability);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::SetMemoryModel(spv::AddressingModel addressing_model_, spv::MemoryModel memory_model_) {
|
void Module::SetMemoryModel(spv::AddressingModel addressing_model_,
|
||||||
|
spv::MemoryModel memory_model_) {
|
||||||
this->addressing_model = addressing_model_;
|
this->addressing_model = addressing_model_;
|
||||||
this->memory_model = memory_model_;
|
this->memory_model = memory_model_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::AddEntryPoint(spv::ExecutionModel execution_model, Id entry_point,
|
void Module::AddEntryPoint(spv::ExecutionModel execution_model, Id entry_point, std::string name,
|
||||||
std::string name, const std::vector<Id>& interfaces) {
|
std::span<const Id> interfaces) {
|
||||||
auto op{std::make_unique<Op>(spv::Op::OpEntryPoint)};
|
auto op{std::make_unique<Op>(spv::Op::OpEntryPoint)};
|
||||||
op->Add(static_cast<u32>(execution_model));
|
op->Add(static_cast<u32>(execution_model));
|
||||||
op->Add(entry_point);
|
op->Add(entry_point);
|
||||||
|
@ -90,7 +91,7 @@ void Module::AddEntryPoint(spv::ExecutionModel execution_model, Id entry_point,
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::AddExecutionMode(Id entry_point, spv::ExecutionMode mode,
|
void Module::AddExecutionMode(Id entry_point, spv::ExecutionMode mode,
|
||||||
const std::vector<Literal>& literals) {
|
std::span<const Literal> literals) {
|
||||||
auto op{std::make_unique<Op>(spv::Op::OpExecutionMode)};
|
auto op{std::make_unique<Op>(spv::Op::OpExecutionMode)};
|
||||||
op->Add(entry_point);
|
op->Add(entry_point);
|
||||||
op->Add(static_cast<u32>(mode));
|
op->Add(static_cast<u32>(mode));
|
||||||
|
@ -123,14 +124,14 @@ Id Module::AddCode(spv::Op opcode, std::optional<u32> id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Id Module::AddDeclaration(std::unique_ptr<Op> op) {
|
Id Module::AddDeclaration(std::unique_ptr<Op> op) {
|
||||||
const auto& found{std::find_if(declarations.begin(), declarations.end(),
|
const auto found = std::find_if(declarations.begin(), declarations.end(),
|
||||||
[&op](const auto& other) { return *other == *op; })};
|
[&op](const auto& other) { return op->Equal(*other); });
|
||||||
if (found != declarations.end()) {
|
if (found != declarations.end()) {
|
||||||
return found->get();
|
return found->get();
|
||||||
}
|
}
|
||||||
const auto id = op.get();
|
const auto id = op.get();
|
||||||
declarations.push_back(std::move(op));
|
declarations.push_back(std::move(op));
|
||||||
bound++;
|
++bound;
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue