mirror of
https://github.com/yuzu-emu/sirit
synced 2024-11-26 02:57:50 +00:00
Use requires
clauses to better disambiguate variadic and non-variadic overloads
Suppose you try to call, say, `AddEntryPoint` with a `std::vector<Id>` as the `interfaces` argument - something that yuzu does. This can match the non-variadic overload, since `std::vector<Id>` is implicitly convertible to the argument type `std::span<const Id>`. But it can also match the variadic overload, and the compiler sees that as a 'better' match because it doesn't require implicit conversion. So it picks that overload and promptly errors out trying to convert `std::vector<Id>` to `Id`. To make the compiler pick the right overload, you would have to explicitly convert to `std::span<const Id>`, which is annoyingly verbose. To avoid this, add `requires` clauses to all variadic convenience overloads, requiring each of the variadic arguments to be convertible to the corresponding element type. If you pass a vector/array/etc., this rules out the variadic overload as a candidate, and the call goes through with the non-variadic overload. Also, use slightly different code to forward to the non-variadic overloads, that works even if the arguments need to be converted. Note: I used this in a WIP branch updating yuzu to the latest version of sirit. Note 2: I tried to run clang-format on this, but it mangled the requires clauses pretty horribly, so I didn't accept its changes. I googled it, and apparently clang-format doesn't properly support concepts yet...
This commit is contained in:
parent
393fccea5b
commit
13396c96ac
1 changed files with 53 additions and 24 deletions
|
@ -13,6 +13,7 @@
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <type_traits>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -61,11 +62,14 @@ public:
|
||||||
std::span<const Id> interfaces = {});
|
std::span<const Id> interfaces = {});
|
||||||
|
|
||||||
/// Adds an entry point.
|
/// Adds an entry point.
|
||||||
|
// TODO: Change std::is_convertible_v to std::convertible_to when compilers
|
||||||
|
// support it; same elsewhere.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
void AddEntryPoint(spv::ExecutionModel execution_model, Id entry_point, std::string_view name,
|
void AddEntryPoint(spv::ExecutionModel execution_model, Id entry_point, std::string_view name,
|
||||||
Ts&&... interfaces) {
|
Ts&&... interfaces) {
|
||||||
AddEntryPoint(execution_model, std::move(entry_point), name,
|
AddEntryPoint(execution_model, std::move(entry_point), name,
|
||||||
std::span<const Id>{std::array{interfaces...}});
|
std::span<const Id>({interfaces...}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Declare an execution mode for an entry point.
|
/// Declare an execution mode for an entry point.
|
||||||
|
@ -74,9 +78,9 @@ public:
|
||||||
|
|
||||||
/// Declare an execution mode for an entry point.
|
/// Declare an execution mode for an entry point.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Literal>)
|
||||||
void AddExecutionMode(Id entry_point, spv::ExecutionMode mode, Ts&&... literals) {
|
void AddExecutionMode(Id entry_point, spv::ExecutionMode mode, Ts&&... literals) {
|
||||||
const Literal stack_literals[] = {std::forward<Ts>(literals)...};
|
AddExecutionMode(entry_point, mode, std::span<const Literal>({literals...}));
|
||||||
AddExecutionMode(entry_point, mode, std::span<const Literal>{stack_literals});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -144,8 +148,9 @@ public:
|
||||||
|
|
||||||
/// Returns type struct.
|
/// Returns type struct.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
Id TypeStruct(Ts&&... members) {
|
Id TypeStruct(Ts&&... members) {
|
||||||
return TypeStruct(std::span<const Id>{std::array{members...}});
|
return TypeStruct(std::span<const Id>({members...}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns type opaque.
|
/// Returns type opaque.
|
||||||
|
@ -159,8 +164,9 @@ public:
|
||||||
|
|
||||||
/// Returns type function.
|
/// Returns type function.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
Id TypeFunction(Id return_type, Ts&&... arguments) {
|
Id TypeFunction(Id return_type, Ts&&... arguments) {
|
||||||
return TypeFunction(return_type, std::span<const Id>{std::array{arguments...}});
|
return TypeFunction(return_type, std::span<const Id>({arguments...}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns type event.
|
/// Returns type event.
|
||||||
|
@ -194,8 +200,9 @@ public:
|
||||||
|
|
||||||
/// Returns a numeric scalar constant.
|
/// Returns a numeric scalar constant.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
Id ConstantComposite(Id result_type, Ts&&... constituents) {
|
Id ConstantComposite(Id result_type, Ts&&... constituents) {
|
||||||
return ConstantComposite(result_type, std::span<const Id>{std::array{constituents...}});
|
return ConstantComposite(result_type, std::span<const Id>({constituents...}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a sampler constant.
|
/// Returns a sampler constant.
|
||||||
|
@ -218,8 +225,9 @@ public:
|
||||||
|
|
||||||
/// Call a function.
|
/// Call a function.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
Id OpFunctionCall(Id result_type, Id function, Ts&&... arguments) {
|
Id OpFunctionCall(Id result_type, Id function, Ts&&... arguments) {
|
||||||
return OpFunctionCall(result_type, function, std::span<const Id>{std::array{arguments...}});
|
return OpFunctionCall(result_type, function, std::span<const Id>({arguments...}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flow
|
// Flow
|
||||||
|
@ -230,10 +238,11 @@ public:
|
||||||
|
|
||||||
/// Declare a structured loop.
|
/// Declare a structured loop.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
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,
|
return OpLoopMerge(merge_block, continue_target, loop_control,
|
||||||
std::span<const Id>{std::array{literals...}});
|
std::span<const Id>({literals...}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Declare a structured selection.
|
/// Declare a structured selection.
|
||||||
|
@ -301,8 +310,9 @@ public:
|
||||||
|
|
||||||
/// 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>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
Id OpAccessChain(Id result_type, Id base, Ts&&... indexes) {
|
Id OpAccessChain(Id result_type, Id base, Ts&&... indexes) {
|
||||||
return OpAccessChain(result_type, base, std::span<const Id>{std::array{indexes...}});
|
return OpAccessChain(result_type, base, std::span<const Id>({indexes...}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract a single, dynamically selected, component of a vector.
|
/// Extract a single, dynamically selected, component of a vector.
|
||||||
|
@ -317,6 +327,7 @@ 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.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Literal>)
|
||||||
Id OpCompositeInsert(Id result_type, Id object, Id composite, Ts&&... indexes) {
|
Id OpCompositeInsert(Id result_type, Id object, Id composite, Ts&&... indexes) {
|
||||||
const Literal stack_indexes[] = {std::forward<Ts>(indexes)...};
|
const Literal stack_indexes[] = {std::forward<Ts>(indexes)...};
|
||||||
return OpCompositeInsert(result_type, object, composite,
|
return OpCompositeInsert(result_type, object, composite,
|
||||||
|
@ -328,6 +339,7 @@ public:
|
||||||
|
|
||||||
/// Extract a part of a composite object.
|
/// Extract a part of a composite object.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Literal>)
|
||||||
Id OpCompositeExtract(Id result_type, Id composite, Ts&&... indexes) {
|
Id OpCompositeExtract(Id result_type, Id composite, Ts&&... indexes) {
|
||||||
const Literal stack_indexes[] = {std::forward<Ts>(indexes)...};
|
const Literal stack_indexes[] = {std::forward<Ts>(indexes)...};
|
||||||
return OpCompositeExtract(result_type, composite, std::span<const Literal>{stack_indexes});
|
return OpCompositeExtract(result_type, composite, std::span<const Literal>{stack_indexes});
|
||||||
|
@ -338,8 +350,9 @@ public:
|
||||||
|
|
||||||
/// 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>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
Id OpCompositeConstruct(Id result_type, Ts&&... ids) {
|
Id OpCompositeConstruct(Id result_type, Ts&&... ids) {
|
||||||
return OpCompositeConstruct(result_type, std::span<const Id>{std::array{ids...}});
|
return OpCompositeConstruct(result_type, std::span<const Id>({ids...}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Annotation
|
// Annotation
|
||||||
|
@ -349,6 +362,7 @@ public:
|
||||||
|
|
||||||
/// Add a decoration to target.
|
/// Add a decoration to target.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Literal>)
|
||||||
Id Decorate(Id target, spv::Decoration decoration, Ts&&... literals) {
|
Id Decorate(Id target, spv::Decoration decoration, Ts&&... literals) {
|
||||||
const Literal stack_literals[] = {std::forward<Ts>(literals)...};
|
const Literal stack_literals[] = {std::forward<Ts>(literals)...};
|
||||||
return Decorate(target, decoration, std::span<const Literal>{stack_literals});
|
return Decorate(target, decoration, std::span<const Literal>{stack_literals});
|
||||||
|
@ -358,6 +372,7 @@ public:
|
||||||
std::span<const Literal> literals = {});
|
std::span<const Literal> literals = {});
|
||||||
|
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Literal>)
|
||||||
Id MemberDecorate(Id structure_type, Literal member, spv::Decoration decoration,
|
Id MemberDecorate(Id structure_type, Literal member, spv::Decoration decoration,
|
||||||
Ts&&... literals) {
|
Ts&&... literals) {
|
||||||
const Literal stack_literals[] = {std::forward<Ts>(literals)...};
|
const Literal stack_literals[] = {std::forward<Ts>(literals)...};
|
||||||
|
@ -621,9 +636,10 @@ public:
|
||||||
|
|
||||||
/// 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>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
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,
|
return OpExtInst(result_type, set, instruction,
|
||||||
std::span<const Id>{std::array{operands...}});
|
std::span<const Id>({operands...}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Result is x if x >= 0; otherwise result is -x.
|
/// Result is x if x >= 0; otherwise result is -x.
|
||||||
|
@ -777,10 +793,11 @@ public:
|
||||||
|
|
||||||
/// Sample an image with an implicit level of detail.
|
/// Sample an image with an implicit level of detail.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
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,
|
||||||
std::span<const Id>{std::array{operands...}});
|
std::span<const Id>({operands...}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sample an image using an explicit level of detail.
|
/// Sample an image using an explicit level of detail.
|
||||||
|
@ -790,10 +807,11 @@ public:
|
||||||
|
|
||||||
/// Sample an image using an explicit level of detail.
|
/// Sample an image using an explicit level of detail.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
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,
|
||||||
std::span<const Id>{std::array{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.
|
||||||
|
@ -803,11 +821,12 @@ public:
|
||||||
|
|
||||||
/// 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>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
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,
|
image_operands,
|
||||||
std::span<const Id>{std::array{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.
|
||||||
|
@ -817,11 +836,12 @@ public:
|
||||||
|
|
||||||
/// 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>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
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,
|
image_operands,
|
||||||
std::span<const Id>{std::array{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.
|
||||||
|
@ -831,10 +851,11 @@ public:
|
||||||
|
|
||||||
/// 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>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
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,
|
||||||
std::span<const Id>{std::array{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.
|
||||||
|
@ -844,10 +865,11 @@ public:
|
||||||
|
|
||||||
/// 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>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
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,
|
||||||
std::span<const Id>{std::array{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
|
||||||
|
@ -859,11 +881,12 @@ public:
|
||||||
/// 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.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
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,
|
image_operands,
|
||||||
std::span<const Id>{std::array{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
|
||||||
|
@ -875,11 +898,12 @@ public:
|
||||||
/// 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.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
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,
|
image_operands,
|
||||||
std::span<const Id>{std::array{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.
|
||||||
|
@ -889,10 +913,11 @@ public:
|
||||||
|
|
||||||
/// 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>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
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,
|
return OpImageFetch(result_type, sampled_image, coordinate, image_operands,
|
||||||
std::span<const Id>{std::array{operands...}});
|
std::span<const Id>({operands...}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gathers the requested component from four texels.
|
/// Gathers the requested component from four texels.
|
||||||
|
@ -902,10 +927,11 @@ public:
|
||||||
|
|
||||||
/// Gathers the requested component from four texels.
|
/// Gathers the requested component from four texels.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
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,
|
||||||
std::span<const Id>{std::array{operands...}});
|
std::span<const Id>({operands...}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gathers the requested depth-comparison from four texels.
|
/// Gathers the requested depth-comparison from four texels.
|
||||||
|
@ -915,10 +941,11 @@ public:
|
||||||
|
|
||||||
/// Gathers the requested depth-comparison from four texels.
|
/// Gathers the requested depth-comparison from four texels.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
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,
|
||||||
std::span<const Id>{std::array{operands...}});
|
std::span<const Id>({operands...}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read a texel from an image without a sampler.
|
/// Read a texel from an image without a sampler.
|
||||||
|
@ -928,10 +955,11 @@ public:
|
||||||
|
|
||||||
/// Read a texel from an image without a sampler.
|
/// Read a texel from an image without a sampler.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
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,
|
return OpImageRead(result_type, sampled_image, coordinate, image_operands,
|
||||||
std::span<const Id>{std::array{operands...}});
|
std::span<const Id>({operands...}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write a texel to an image without a sampler.
|
/// Write a texel to an image without a sampler.
|
||||||
|
@ -941,10 +969,11 @@ public:
|
||||||
|
|
||||||
/// Write a texel to an image without a sampler.
|
/// Write a texel to an image without a sampler.
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
|
requires (... && std::is_convertible_v<Ts, Id>)
|
||||||
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,
|
return OpImageWrite(image, coordinate, texel, image_operands,
|
||||||
std::span<const Id>{std::array{operands...}});
|
std::span<const Id>({operands...}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the image from a sampled image.
|
/// Extract the image from a sampled image.
|
||||||
|
|
Loading…
Reference in a new issue