mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-18 09:25:25 +00:00
Add semantic::Intrinsic
semantic::Intrinsic derives from semantic::CallTarget, which can be obtained from the Target() accessor on the CallExpression. Flesh out semantic::Parameter to contain a `Usage` - extra metadata for the parameter. The information in `Intrinsic` is enough to remove the `semantic::IntrinsicCall` and `semantic::TextureIntrinsicCall` types. Change-Id: Ida9c193674ad8605d8f12f6a1d27f38c7d008434 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/40503 Reviewed-by: dan sinclair <dsinclair@chromium.org> Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
committed by
Commit Bot service account
parent
bab3197fda
commit
316f9f6b6d
@@ -26,96 +26,17 @@ namespace semantic {
|
||||
class Call : public Castable<Call, Expression> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param return_type the return type of the call
|
||||
explicit Call(type::Type* return_type);
|
||||
/// @param target the call target
|
||||
explicit Call(const CallTarget* target);
|
||||
|
||||
/// Destructor
|
||||
~Call() override;
|
||||
};
|
||||
|
||||
/// IntrinsicCall holds semantic information for ast::CallExpression nodes that
|
||||
/// call intrinsic functions.
|
||||
class IntrinsicCall : public Castable<IntrinsicCall, Call> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param return_type the return type of the call
|
||||
/// @param intrinsic the call target intrinsic
|
||||
IntrinsicCall(type::Type* return_type, IntrinsicType intrinsic);
|
||||
|
||||
/// Destructor
|
||||
~IntrinsicCall() override;
|
||||
|
||||
/// @returns the target intrinsic for the call
|
||||
IntrinsicType intrinsic() const { return intrinsic_; }
|
||||
/// @return the target of the call
|
||||
const CallTarget* Target() const { return target_; }
|
||||
|
||||
private:
|
||||
IntrinsicType const intrinsic_;
|
||||
};
|
||||
|
||||
/// TextureIntrinsicCall holds semantic information for ast::CallExpression
|
||||
/// nodes that call intrinsic texture functions.
|
||||
class TextureIntrinsicCall
|
||||
: public Castable<TextureIntrinsicCall, IntrinsicCall> {
|
||||
public:
|
||||
/// Parameters describes the parameters for the texture function.
|
||||
struct Parameters {
|
||||
/// kNotUsed is the constant that indicates the given parameter is not part
|
||||
/// of the texture function signature.
|
||||
static constexpr const size_t kNotUsed = ~static_cast<size_t>(0u);
|
||||
/// Index holds each of the possible parameter indices. If a parameter index
|
||||
/// is equal to `kNotUsed` then this parameter is not used by the function.
|
||||
struct Index {
|
||||
/// Constructor
|
||||
Index();
|
||||
/// Copy constructor
|
||||
Index(const Index&);
|
||||
/// `array_index` parameter index.
|
||||
size_t array_index = kNotUsed;
|
||||
/// `bias` parameter index.
|
||||
size_t bias = kNotUsed;
|
||||
/// `coords` parameter index.
|
||||
size_t coords = kNotUsed;
|
||||
/// `depth_ref` parameter index.
|
||||
size_t depth_ref = kNotUsed;
|
||||
/// `ddx` parameter index.
|
||||
size_t ddx = kNotUsed;
|
||||
/// `ddy` parameter index.
|
||||
size_t ddy = kNotUsed;
|
||||
/// `level` parameter index.
|
||||
size_t level = kNotUsed;
|
||||
/// `offset` parameter index.
|
||||
size_t offset = kNotUsed;
|
||||
/// `sampler` parameter index.
|
||||
size_t sampler = kNotUsed;
|
||||
/// `sample_index` parameter index.
|
||||
size_t sample_index = kNotUsed;
|
||||
/// `texture` parameter index.
|
||||
size_t texture = kNotUsed;
|
||||
/// `value` parameter index.
|
||||
size_t value = kNotUsed;
|
||||
};
|
||||
/// The indices of all possible parameters.
|
||||
Index idx;
|
||||
/// Total number of parameters.
|
||||
size_t count = 0;
|
||||
};
|
||||
|
||||
/// Constructor
|
||||
/// @param return_type the return type of the call
|
||||
/// @param intrinsic the call target intrinsic
|
||||
/// @param params the overload parameter info
|
||||
TextureIntrinsicCall(type::Type* return_type,
|
||||
IntrinsicType intrinsic,
|
||||
const Parameters& params);
|
||||
|
||||
/// Destructor
|
||||
~TextureIntrinsicCall() override;
|
||||
|
||||
/// @return the texture call's parameters
|
||||
const Parameters& Params() const { return params_; }
|
||||
|
||||
private:
|
||||
const Parameters params_;
|
||||
CallTarget const* const target_;
|
||||
};
|
||||
|
||||
} // namespace semantic
|
||||
|
||||
@@ -32,18 +32,52 @@ namespace semantic {
|
||||
|
||||
/// Parameter describes a single parameter of a call target
|
||||
struct Parameter {
|
||||
/// Usage is extra metadata for identifying a parameter based on its overload
|
||||
/// position
|
||||
enum class Usage {
|
||||
kNone,
|
||||
kArrayIndex,
|
||||
kBias,
|
||||
kCoords,
|
||||
kDepthRef,
|
||||
kDdx,
|
||||
kDdy,
|
||||
kLevel,
|
||||
kOffset,
|
||||
kSampler,
|
||||
kSampleIndex,
|
||||
kTexture,
|
||||
kValue,
|
||||
};
|
||||
|
||||
/// Parameter type
|
||||
type::Type* type;
|
||||
type::Type* const type;
|
||||
/// Parameter usage
|
||||
Usage const usage = Usage::kNone;
|
||||
};
|
||||
|
||||
/// @returns a string representation of the given parameter usage.
|
||||
const char* str(Parameter::Usage usage);
|
||||
|
||||
/// Parameters is a list of Parameter
|
||||
using Parameters = std::vector<Parameter>;
|
||||
|
||||
/// @param parameters the list of parameters
|
||||
/// @param usage the parameter usage to find
|
||||
/// @returns the index of the parameter with the given usage, or -1 if no
|
||||
/// parameter with the given usage exists.
|
||||
int IndexOf(const Parameters& parameters, Parameter::Usage usage);
|
||||
|
||||
/// CallTarget is the base for callable functions
|
||||
class CallTarget : public Castable<CallTarget, Node> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param return_type the return type of the call target
|
||||
/// @param parameters the parameters for the call target
|
||||
explicit CallTarget(const semantic::Parameters& parameters);
|
||||
CallTarget(type::Type* return_type, const semantic::Parameters& parameters);
|
||||
|
||||
/// @return the return type of the call target
|
||||
type::Type* ReturnType() const { return return_type_; }
|
||||
|
||||
/// Destructor
|
||||
~CallTarget() override;
|
||||
@@ -52,7 +86,8 @@ class CallTarget : public Castable<CallTarget, Node> {
|
||||
const Parameters& Parameters() const { return parameters_; }
|
||||
|
||||
private:
|
||||
semantic::Parameters parameters_;
|
||||
type::Type* const return_type_;
|
||||
semantic::Parameters const parameters_;
|
||||
};
|
||||
|
||||
} // namespace semantic
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "src/semantic/call_target.h"
|
||||
|
||||
namespace tint {
|
||||
namespace semantic {
|
||||
|
||||
@@ -102,39 +104,37 @@ enum class IntrinsicType {
|
||||
kTrunc
|
||||
};
|
||||
|
||||
/// Emits the name of the intrinsic function. The spelling,
|
||||
/// including case, matches the name in the WGSL spec.
|
||||
std::ostream& operator<<(std::ostream& out, IntrinsicType i);
|
||||
|
||||
namespace intrinsic {
|
||||
/// @returns the name of the intrinsic function type. The spelling, including
|
||||
/// case, matches the name in the WGSL spec.
|
||||
const char* str(IntrinsicType i);
|
||||
|
||||
/// Determines if the given `i` is a coarse derivative
|
||||
/// @param i the intrinsic
|
||||
/// @param i the intrinsic type
|
||||
/// @returns true if the given derivative is coarse.
|
||||
bool IsCoarseDerivative(IntrinsicType i);
|
||||
bool IsCoarseDerivativeIntrinsic(IntrinsicType i);
|
||||
|
||||
/// Determines if the given `i` is a fine derivative
|
||||
/// @param i the intrinsic
|
||||
/// @param i the intrinsic type
|
||||
/// @returns true if the given derivative is fine.
|
||||
bool IsFineDerivative(IntrinsicType i);
|
||||
bool IsFineDerivativeIntrinsic(IntrinsicType i);
|
||||
|
||||
/// Determine if the given `i` is a derivative intrinsic
|
||||
/// @param i the intrinsic
|
||||
/// @param i the intrinsic type
|
||||
/// @returns true if the given `i` is a derivative intrinsic
|
||||
bool IsDerivative(IntrinsicType i);
|
||||
bool IsDerivativeIntrinsic(IntrinsicType i);
|
||||
|
||||
/// Determines if the given `i` is a float classification intrinsic
|
||||
/// @param i the intrinsic
|
||||
/// @param i the intrinsic type
|
||||
/// @returns true if the given `i` is a float intrinsic
|
||||
bool IsFloatClassificationIntrinsic(IntrinsicType i);
|
||||
|
||||
/// Determines if the given `i` is a texture operation intrinsic
|
||||
/// @param i the intrinsic
|
||||
/// @param i the intrinsic type
|
||||
/// @returns true if the given `i` is a texture operation intrinsic
|
||||
bool IsTextureIntrinsic(IntrinsicType i);
|
||||
|
||||
/// Determines if the given `i` is a image query intrinsic
|
||||
/// @param i the intrinsic
|
||||
/// @param i the intrinsic type
|
||||
/// @returns true if the given `i` is a image query intrinsic
|
||||
bool IsImageQueryIntrinsic(IntrinsicType i);
|
||||
|
||||
@@ -143,11 +143,56 @@ bool IsImageQueryIntrinsic(IntrinsicType i);
|
||||
/// @returns true if the given `i` is a data packing intrinsic
|
||||
bool IsDataPackingIntrinsic(IntrinsicType i);
|
||||
|
||||
/// @returns the name of the intrinsic function. The spelling, including case,
|
||||
/// matches the name in the WGSL spec.
|
||||
const char* str(IntrinsicType i);
|
||||
/// Intrinsic holds the semantic information for an intrinsic function.
|
||||
class Intrinsic : public Castable<Intrinsic, CallTarget> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param type the intrinsic type
|
||||
/// @param return_type the return type for the intrinsic call
|
||||
/// @param parameters the parameters for the intrinsic overload
|
||||
Intrinsic(IntrinsicType type,
|
||||
type::Type* return_type,
|
||||
const semantic::Parameters& parameters);
|
||||
|
||||
/// Destructor
|
||||
~Intrinsic() override;
|
||||
|
||||
/// @return the type of the intrinsic
|
||||
IntrinsicType Type() const { return type_; }
|
||||
|
||||
/// @returns the name of the intrinsic function type. The spelling, including
|
||||
/// case, matches the name in the WGSL spec.
|
||||
const char* str() const;
|
||||
|
||||
/// @returns true if intrinsic is a coarse derivative intrinsic
|
||||
bool IsCoarseDerivative() const;
|
||||
|
||||
/// @returns true if intrinsic is a fine a derivative intrinsic
|
||||
bool IsFineDerivative() const;
|
||||
|
||||
/// @returns true if intrinsic is a derivative intrinsic
|
||||
bool IsDerivative() const;
|
||||
|
||||
/// @returns true if intrinsic is a float intrinsic
|
||||
bool IsFloatClassification() const;
|
||||
|
||||
/// @returns true if intrinsic is a texture operation intrinsic
|
||||
bool IsTexture() const;
|
||||
|
||||
/// @returns true if intrinsic is a image query intrinsic
|
||||
bool IsImageQuery() const;
|
||||
|
||||
/// @returns true if intrinsic is a data packing intrinsic
|
||||
bool IsDataPacking() const;
|
||||
|
||||
private:
|
||||
IntrinsicType const type_;
|
||||
};
|
||||
|
||||
/// Emits the name of the intrinsic function type. The spelling, including case,
|
||||
/// matches the name in the WGSL spec.
|
||||
std::ostream& operator<<(std::ostream& out, IntrinsicType i);
|
||||
|
||||
} // namespace intrinsic
|
||||
} // namespace semantic
|
||||
} // namespace tint
|
||||
|
||||
|
||||
@@ -15,30 +15,14 @@
|
||||
#include "src/semantic/call.h"
|
||||
|
||||
TINT_INSTANTIATE_CLASS_ID(tint::semantic::Call);
|
||||
TINT_INSTANTIATE_CLASS_ID(tint::semantic::IntrinsicCall);
|
||||
TINT_INSTANTIATE_CLASS_ID(tint::semantic::TextureIntrinsicCall);
|
||||
|
||||
namespace tint {
|
||||
namespace semantic {
|
||||
|
||||
Call::Call(type::Type* return_type) : Base(return_type) {}
|
||||
Call::Call(const CallTarget* target)
|
||||
: Base(target->ReturnType()), target_(target) {}
|
||||
|
||||
Call::~Call() = default;
|
||||
|
||||
IntrinsicCall::IntrinsicCall(type::Type* return_type, IntrinsicType intrinsic)
|
||||
: Base(return_type), intrinsic_(intrinsic) {}
|
||||
|
||||
IntrinsicCall::~IntrinsicCall() = default;
|
||||
|
||||
TextureIntrinsicCall::TextureIntrinsicCall(type::Type* return_type,
|
||||
IntrinsicType intrinsic,
|
||||
const Parameters& params)
|
||||
: Base(return_type, intrinsic), params_(params) {}
|
||||
|
||||
TextureIntrinsicCall::~TextureIntrinsicCall() = default;
|
||||
|
||||
TextureIntrinsicCall::Parameters::Index::Index() = default;
|
||||
TextureIntrinsicCall::Parameters::Index::Index(const Index&) = default;
|
||||
|
||||
} // namespace semantic
|
||||
} // namespace tint
|
||||
|
||||
@@ -21,10 +21,50 @@ TINT_INSTANTIATE_CLASS_ID(tint::semantic::CallTarget);
|
||||
namespace tint {
|
||||
namespace semantic {
|
||||
|
||||
CallTarget::CallTarget(const semantic::Parameters& parameters)
|
||||
: parameters_(parameters) {}
|
||||
CallTarget::CallTarget(type::Type* return_type,
|
||||
const semantic::Parameters& parameters)
|
||||
: return_type_(return_type), parameters_(parameters) {}
|
||||
|
||||
CallTarget::~CallTarget() = default;
|
||||
|
||||
int IndexOf(const Parameters& parameters, Parameter::Usage usage) {
|
||||
for (size_t i = 0; i < parameters.size(); i++) {
|
||||
if (parameters[i].usage == usage) {
|
||||
return static_cast<int>(i);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char* str(Parameter::Usage usage) {
|
||||
switch (usage) {
|
||||
case Parameter::Usage::kArrayIndex:
|
||||
return "array_index";
|
||||
case Parameter::Usage::kBias:
|
||||
return "bias";
|
||||
case Parameter::Usage::kCoords:
|
||||
return "coords";
|
||||
case Parameter::Usage::kDepthRef:
|
||||
return "depth_ref";
|
||||
case Parameter::Usage::kDdx:
|
||||
return "ddx";
|
||||
case Parameter::Usage::kDdy:
|
||||
return "ddy";
|
||||
case Parameter::Usage::kLevel:
|
||||
return "level";
|
||||
case Parameter::Usage::kOffset:
|
||||
return "offset";
|
||||
case Parameter::Usage::kSampler:
|
||||
return "sampler";
|
||||
case Parameter::Usage::kSampleIndex:
|
||||
return "sample_index";
|
||||
case Parameter::Usage::kTexture:
|
||||
return "texture";
|
||||
case Parameter::Usage::kValue:
|
||||
return "value";
|
||||
default:
|
||||
return "<unknown>";
|
||||
}
|
||||
}
|
||||
} // namespace semantic
|
||||
} // namespace tint
|
||||
|
||||
@@ -37,7 +37,7 @@ Parameters GetParameters(ast::Function* ast) {
|
||||
semantic::Parameters parameters;
|
||||
parameters.reserve(ast->params().size());
|
||||
for (auto* param : ast->params()) {
|
||||
parameters.emplace_back(Parameter{param->type()});
|
||||
parameters.emplace_back(Parameter{param->type(), Parameter::Usage::kNone});
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
@@ -48,7 +48,7 @@ Function::Function(ast::Function* ast,
|
||||
std::vector<const Variable*> referenced_module_vars,
|
||||
std::vector<const Variable*> local_referenced_module_vars,
|
||||
std::vector<Symbol> ancestor_entry_points)
|
||||
: Base(GetParameters(ast)),
|
||||
: Base(ast->return_type(), GetParameters(ast)),
|
||||
referenced_module_vars_(std::move(referenced_module_vars)),
|
||||
local_referenced_module_vars_(std::move(local_referenced_module_vars)),
|
||||
ancestor_entry_points_(std::move(ancestor_entry_points)) {}
|
||||
|
||||
@@ -14,15 +14,19 @@
|
||||
|
||||
#include "src/semantic/intrinsic.h"
|
||||
|
||||
TINT_INSTANTIATE_CLASS_ID(tint::semantic::Intrinsic);
|
||||
|
||||
namespace tint {
|
||||
namespace semantic {
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, IntrinsicType i) {
|
||||
out << intrinsic::str(i);
|
||||
out << str(i);
|
||||
return out;
|
||||
}
|
||||
|
||||
namespace intrinsic {
|
||||
const char* Intrinsic::str() const {
|
||||
return semantic::str(type_);
|
||||
}
|
||||
|
||||
const char* str(IntrinsicType i) {
|
||||
/// The emitted name matches the spelling in the WGSL spec.
|
||||
@@ -188,20 +192,20 @@ const char* str(IntrinsicType i) {
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
bool IsCoarseDerivative(IntrinsicType i) {
|
||||
bool IsCoarseDerivativeIntrinsic(IntrinsicType i) {
|
||||
return i == IntrinsicType::kDpdxCoarse || i == IntrinsicType::kDpdyCoarse ||
|
||||
i == IntrinsicType::kFwidthCoarse;
|
||||
}
|
||||
|
||||
bool IsFineDerivative(IntrinsicType i) {
|
||||
bool IsFineDerivativeIntrinsic(IntrinsicType i) {
|
||||
return i == IntrinsicType::kDpdxFine || i == IntrinsicType::kDpdyFine ||
|
||||
i == IntrinsicType::kFwidthFine;
|
||||
}
|
||||
|
||||
bool IsDerivative(IntrinsicType i) {
|
||||
bool IsDerivativeIntrinsic(IntrinsicType i) {
|
||||
return i == IntrinsicType::kDpdx || i == IntrinsicType::kDpdy ||
|
||||
i == IntrinsicType::kFwidth || IsCoarseDerivative(i) ||
|
||||
IsFineDerivative(i);
|
||||
i == IntrinsicType::kFwidth || IsCoarseDerivativeIntrinsic(i) ||
|
||||
IsFineDerivativeIntrinsic(i);
|
||||
}
|
||||
|
||||
bool IsFloatClassificationIntrinsic(IntrinsicType i) {
|
||||
@@ -220,7 +224,7 @@ bool IsTextureIntrinsic(IntrinsicType i) {
|
||||
}
|
||||
|
||||
bool IsImageQueryIntrinsic(IntrinsicType i) {
|
||||
return i == semantic::IntrinsicType::kTextureDimensions ||
|
||||
return i == IntrinsicType::kTextureDimensions ||
|
||||
i == IntrinsicType::kTextureNumLayers ||
|
||||
i == IntrinsicType::kTextureNumLevels ||
|
||||
i == IntrinsicType::kTextureNumSamples;
|
||||
@@ -234,6 +238,40 @@ bool IsDataPackingIntrinsic(IntrinsicType i) {
|
||||
i == IntrinsicType::kPack2x16Float;
|
||||
}
|
||||
|
||||
} // namespace intrinsic
|
||||
Intrinsic::Intrinsic(IntrinsicType type,
|
||||
type::Type* return_type,
|
||||
const semantic::Parameters& parameters)
|
||||
: Base(return_type, parameters), type_(type) {}
|
||||
|
||||
Intrinsic::~Intrinsic() = default;
|
||||
|
||||
bool Intrinsic::IsCoarseDerivative() const {
|
||||
return IsCoarseDerivativeIntrinsic(type_);
|
||||
}
|
||||
|
||||
bool Intrinsic::IsFineDerivative() const {
|
||||
return IsFineDerivativeIntrinsic(type_);
|
||||
}
|
||||
|
||||
bool Intrinsic::IsDerivative() const {
|
||||
return IsDerivativeIntrinsic(type_);
|
||||
}
|
||||
|
||||
bool Intrinsic::IsFloatClassification() const {
|
||||
return IsFloatClassificationIntrinsic(type_);
|
||||
}
|
||||
|
||||
bool Intrinsic::IsTexture() const {
|
||||
return IsTextureIntrinsic(type_);
|
||||
}
|
||||
|
||||
bool Intrinsic::IsImageQuery() const {
|
||||
return IsImageQueryIntrinsic(type_);
|
||||
}
|
||||
|
||||
bool Intrinsic::IsDataPacking() const {
|
||||
return IsDataPackingIntrinsic(type_);
|
||||
}
|
||||
|
||||
} // namespace semantic
|
||||
} // namespace tint
|
||||
|
||||
Reference in New Issue
Block a user