mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-05-16 04:11:25 +00:00
tint: Resolve @interpolate() args as expressions
This CL makes the builtin argument resolve as a shadowable enumerator expression. Bug: tint:1841 Bug: tint:1845 Change-Id: I5000ea91771fabb460c80c164bc7708fbbb0288c Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/120722 Reviewed-by: Dan Sinclair <dsinclair@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
650426b187
commit
f0b4dbb82d
@ -25,8 +25,8 @@ namespace tint::ast {
|
|||||||
InterpolateAttribute::InterpolateAttribute(ProgramID pid,
|
InterpolateAttribute::InterpolateAttribute(ProgramID pid,
|
||||||
NodeID nid,
|
NodeID nid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
builtin::InterpolationType ty,
|
const Expression* ty,
|
||||||
builtin::InterpolationSampling smpl)
|
const Expression* smpl)
|
||||||
: Base(pid, nid, src), type(ty), sampling(smpl) {}
|
: Base(pid, nid, src), type(ty), sampling(smpl) {}
|
||||||
|
|
||||||
InterpolateAttribute::~InterpolateAttribute() = default;
|
InterpolateAttribute::~InterpolateAttribute() = default;
|
||||||
@ -38,7 +38,9 @@ std::string InterpolateAttribute::Name() const {
|
|||||||
const InterpolateAttribute* InterpolateAttribute::Clone(CloneContext* ctx) const {
|
const InterpolateAttribute* InterpolateAttribute::Clone(CloneContext* ctx) const {
|
||||||
// Clone arguments outside of create() call to have deterministic ordering
|
// Clone arguments outside of create() call to have deterministic ordering
|
||||||
auto src = ctx->Clone(source);
|
auto src = ctx->Clone(source);
|
||||||
return ctx->dst->create<InterpolateAttribute>(src, type, sampling);
|
auto* ty = ctx->Clone(type);
|
||||||
|
auto* smpl = ctx->Clone(sampling);
|
||||||
|
return ctx->dst->create<InterpolateAttribute>(src, ty, smpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace tint::ast
|
} // namespace tint::ast
|
||||||
|
@ -19,8 +19,11 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/tint/ast/attribute.h"
|
#include "src/tint/ast/attribute.h"
|
||||||
#include "src/tint/builtin/interpolation_sampling.h"
|
|
||||||
#include "src/tint/builtin/interpolation_type.h"
|
// Forward declarations
|
||||||
|
namespace tint::ast {
|
||||||
|
class Expression;
|
||||||
|
}
|
||||||
|
|
||||||
namespace tint::ast {
|
namespace tint::ast {
|
||||||
|
|
||||||
@ -36,8 +39,8 @@ class InterpolateAttribute final : public Castable<InterpolateAttribute, Attribu
|
|||||||
InterpolateAttribute(ProgramID pid,
|
InterpolateAttribute(ProgramID pid,
|
||||||
NodeID nid,
|
NodeID nid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
builtin::InterpolationType type,
|
const Expression* type,
|
||||||
builtin::InterpolationSampling sampling);
|
const Expression* sampling);
|
||||||
~InterpolateAttribute() override;
|
~InterpolateAttribute() override;
|
||||||
|
|
||||||
/// @returns the WGSL name for the attribute
|
/// @returns the WGSL name for the attribute
|
||||||
@ -50,10 +53,10 @@ class InterpolateAttribute final : public Castable<InterpolateAttribute, Attribu
|
|||||||
const InterpolateAttribute* Clone(CloneContext* ctx) const override;
|
const InterpolateAttribute* Clone(CloneContext* ctx) const override;
|
||||||
|
|
||||||
/// The interpolation type
|
/// The interpolation type
|
||||||
const builtin::InterpolationType type;
|
const Expression* const type;
|
||||||
|
|
||||||
/// The interpolation sampling
|
/// The interpolation sampling
|
||||||
const builtin::InterpolationSampling sampling;
|
const Expression* const sampling;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::ast
|
} // namespace tint::ast
|
||||||
|
@ -25,10 +25,10 @@ namespace {
|
|||||||
using InterpolateAttributeTest = TestHelper;
|
using InterpolateAttributeTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(InterpolateAttributeTest, Creation) {
|
TEST_F(InterpolateAttributeTest, Creation) {
|
||||||
auto* d = create<InterpolateAttribute>(builtin::InterpolationType::kLinear,
|
auto* d =
|
||||||
builtin::InterpolationSampling::kCenter);
|
Interpolate(builtin::InterpolationType::kLinear, builtin::InterpolationSampling::kCenter);
|
||||||
EXPECT_EQ(builtin::InterpolationType::kLinear, d->type);
|
CheckIdentifier(Symbols(), d->type, "linear");
|
||||||
EXPECT_EQ(builtin::InterpolationSampling::kCenter, d->sampling);
|
CheckIdentifier(Symbols(), d->sampling, "center");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
#include "src/tint/ast/var.h"
|
#include "src/tint/ast/var.h"
|
||||||
#include "src/tint/builtin/builtin_value.h"
|
#include "src/tint/builtin/builtin_value.h"
|
||||||
#include "src/tint/builtin/extension.h"
|
#include "src/tint/builtin/extension.h"
|
||||||
|
#include "src/tint/builtin/interpolation_sampling.h"
|
||||||
|
#include "src/tint/builtin/interpolation_type.h"
|
||||||
#include "src/tint/sem/builtin_enum_expression.h"
|
#include "src/tint/sem/builtin_enum_expression.h"
|
||||||
#include "src/tint/sem/call.h"
|
#include "src/tint/sem/call.h"
|
||||||
#include "src/tint/sem/function.h"
|
#include "src/tint/sem/function.h"
|
||||||
@ -117,59 +119,6 @@ std::tuple<ComponentType, CompositionType> CalculateComponentAndComposition(
|
|||||||
return {componentType, compositionType};
|
return {componentType, compositionType};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<InterpolationType, InterpolationSampling> CalculateInterpolationData(
|
|
||||||
const type::Type* type,
|
|
||||||
utils::VectorRef<const ast::Attribute*> attributes) {
|
|
||||||
auto* interpolation_attribute = ast::GetAttribute<ast::InterpolateAttribute>(attributes);
|
|
||||||
if (type->is_integer_scalar_or_vector()) {
|
|
||||||
return {InterpolationType::kFlat, InterpolationSampling::kNone};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!interpolation_attribute) {
|
|
||||||
return {InterpolationType::kPerspective, InterpolationSampling::kCenter};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ast_interpolation_type = interpolation_attribute->type;
|
|
||||||
auto ast_sampling_type = interpolation_attribute->sampling;
|
|
||||||
if (ast_interpolation_type != builtin::InterpolationType::kFlat &&
|
|
||||||
ast_sampling_type == builtin::InterpolationSampling::kUndefined) {
|
|
||||||
ast_sampling_type = builtin::InterpolationSampling::kCenter;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto interpolation_type = InterpolationType::kUnknown;
|
|
||||||
switch (ast_interpolation_type) {
|
|
||||||
case builtin::InterpolationType::kPerspective:
|
|
||||||
interpolation_type = InterpolationType::kPerspective;
|
|
||||||
break;
|
|
||||||
case builtin::InterpolationType::kLinear:
|
|
||||||
interpolation_type = InterpolationType::kLinear;
|
|
||||||
break;
|
|
||||||
case builtin::InterpolationType::kFlat:
|
|
||||||
interpolation_type = InterpolationType::kFlat;
|
|
||||||
break;
|
|
||||||
case builtin::InterpolationType::kUndefined:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto sampling_type = InterpolationSampling::kUnknown;
|
|
||||||
switch (ast_sampling_type) {
|
|
||||||
case builtin::InterpolationSampling::kUndefined:
|
|
||||||
sampling_type = InterpolationSampling::kNone;
|
|
||||||
break;
|
|
||||||
case builtin::InterpolationSampling::kCenter:
|
|
||||||
sampling_type = InterpolationSampling::kCenter;
|
|
||||||
break;
|
|
||||||
case builtin::InterpolationSampling::kCentroid:
|
|
||||||
sampling_type = InterpolationSampling::kCentroid;
|
|
||||||
break;
|
|
||||||
case builtin::InterpolationSampling::kSample:
|
|
||||||
sampling_type = InterpolationSampling::kSample;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {interpolation_type, sampling_type};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Inspector::Inspector(const Program* program) : program_(program) {}
|
Inspector::Inspector(const Program* program) : program_(program) {}
|
||||||
@ -887,6 +836,70 @@ void Inspector::GenerateSamplerTargets() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::tuple<InterpolationType, InterpolationSampling> Inspector::CalculateInterpolationData(
|
||||||
|
const type::Type* type,
|
||||||
|
utils::VectorRef<const ast::Attribute*> attributes) const {
|
||||||
|
auto* interpolation_attribute = ast::GetAttribute<ast::InterpolateAttribute>(attributes);
|
||||||
|
if (type->is_integer_scalar_or_vector()) {
|
||||||
|
return {InterpolationType::kFlat, InterpolationSampling::kNone};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!interpolation_attribute) {
|
||||||
|
return {InterpolationType::kPerspective, InterpolationSampling::kCenter};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& sem = program_->Sem();
|
||||||
|
|
||||||
|
auto ast_interpolation_type = sem.Get<sem::BuiltinEnumExpression<builtin::InterpolationType>>(
|
||||||
|
interpolation_attribute->type)
|
||||||
|
->Value();
|
||||||
|
|
||||||
|
auto ast_sampling_type = builtin::InterpolationSampling::kUndefined;
|
||||||
|
if (interpolation_attribute->sampling) {
|
||||||
|
ast_sampling_type = sem.Get<sem::BuiltinEnumExpression<builtin::InterpolationSampling>>(
|
||||||
|
interpolation_attribute->sampling)
|
||||||
|
->Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ast_interpolation_type != builtin::InterpolationType::kFlat &&
|
||||||
|
ast_sampling_type == builtin::InterpolationSampling::kUndefined) {
|
||||||
|
ast_sampling_type = builtin::InterpolationSampling::kCenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto interpolation_type = InterpolationType::kUnknown;
|
||||||
|
switch (ast_interpolation_type) {
|
||||||
|
case builtin::InterpolationType::kPerspective:
|
||||||
|
interpolation_type = InterpolationType::kPerspective;
|
||||||
|
break;
|
||||||
|
case builtin::InterpolationType::kLinear:
|
||||||
|
interpolation_type = InterpolationType::kLinear;
|
||||||
|
break;
|
||||||
|
case builtin::InterpolationType::kFlat:
|
||||||
|
interpolation_type = InterpolationType::kFlat;
|
||||||
|
break;
|
||||||
|
case builtin::InterpolationType::kUndefined:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto sampling_type = InterpolationSampling::kUnknown;
|
||||||
|
switch (ast_sampling_type) {
|
||||||
|
case builtin::InterpolationSampling::kUndefined:
|
||||||
|
sampling_type = InterpolationSampling::kNone;
|
||||||
|
break;
|
||||||
|
case builtin::InterpolationSampling::kCenter:
|
||||||
|
sampling_type = InterpolationSampling::kCenter;
|
||||||
|
break;
|
||||||
|
case builtin::InterpolationSampling::kCentroid:
|
||||||
|
sampling_type = InterpolationSampling::kCentroid;
|
||||||
|
break;
|
||||||
|
case builtin::InterpolationSampling::kSample:
|
||||||
|
sampling_type = InterpolationSampling::kSample;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {interpolation_type, sampling_type};
|
||||||
|
}
|
||||||
|
|
||||||
template <size_t N, typename F>
|
template <size_t N, typename F>
|
||||||
void Inspector::GetOriginatingResources(std::array<const ast::Expression*, N> exprs, F&& callback) {
|
void Inspector::GetOriginatingResources(std::array<const ast::Expression*, N> exprs, F&& callback) {
|
||||||
if (TINT_UNLIKELY(!program_->IsValid())) {
|
if (TINT_UNLIKELY(!program_->IsValid())) {
|
||||||
|
@ -224,6 +224,13 @@ class Inspector {
|
|||||||
/// Constructs |sampler_targets_| if it hasn't already been instantiated.
|
/// Constructs |sampler_targets_| if it hasn't already been instantiated.
|
||||||
void GenerateSamplerTargets();
|
void GenerateSamplerTargets();
|
||||||
|
|
||||||
|
/// @param type the type of the parameter or structure member
|
||||||
|
/// @param attributes attributes associated with the parameter or structure member
|
||||||
|
/// @returns the interpolation type and sampling modes for the value
|
||||||
|
std::tuple<InterpolationType, InterpolationSampling> CalculateInterpolationData(
|
||||||
|
const type::Type* type,
|
||||||
|
utils::VectorRef<const ast::Attribute*> attributes) const;
|
||||||
|
|
||||||
/// For a N-uple of expressions, resolve to the appropriate global resources
|
/// For a N-uple of expressions, resolve to the appropriate global resources
|
||||||
/// and call 'cb'.
|
/// and call 'cb'.
|
||||||
/// 'cb' may be called multiple times.
|
/// 'cb' may be called multiple times.
|
||||||
|
@ -75,6 +75,8 @@
|
|||||||
#include "src/tint/ast/while_statement.h"
|
#include "src/tint/ast/while_statement.h"
|
||||||
#include "src/tint/ast/workgroup_attribute.h"
|
#include "src/tint/ast/workgroup_attribute.h"
|
||||||
#include "src/tint/builtin/extension.h"
|
#include "src/tint/builtin/extension.h"
|
||||||
|
#include "src/tint/builtin/interpolation_sampling.h"
|
||||||
|
#include "src/tint/builtin/interpolation_type.h"
|
||||||
#include "src/tint/constant/composite.h"
|
#include "src/tint/constant/composite.h"
|
||||||
#include "src/tint/constant/splat.h"
|
#include "src/tint/constant/splat.h"
|
||||||
#include "src/tint/constant/value.h"
|
#include "src/tint/constant/value.h"
|
||||||
@ -3459,26 +3461,49 @@ class ProgramBuilder {
|
|||||||
return create<ast::BuiltinAttribute>(source_, Expr(std::forward<BUILTIN>(builtin)));
|
return create<ast::BuiltinAttribute>(source_, Expr(std::forward<BUILTIN>(builtin)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates an ast::InterpolateAttribute
|
||||||
|
/// @param type the interpolation type
|
||||||
|
/// @returns the interpolate attribute pointer
|
||||||
|
template <typename TYPE, typename = DisableIfSource<TYPE>>
|
||||||
|
const ast::InterpolateAttribute* Interpolate(TYPE&& type) {
|
||||||
|
return Interpolate(source_, std::forward<TYPE>(type));
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates an ast::InterpolateAttribute
|
/// Creates an ast::InterpolateAttribute
|
||||||
/// @param source the source information
|
/// @param source the source information
|
||||||
/// @param type the interpolation type
|
/// @param type the interpolation type
|
||||||
/// @param sampling the interpolation sampling
|
|
||||||
/// @returns the interpolate attribute pointer
|
/// @returns the interpolate attribute pointer
|
||||||
const ast::InterpolateAttribute* Interpolate(
|
template <typename TYPE>
|
||||||
const Source& source,
|
const ast::InterpolateAttribute* Interpolate(const Source& source, TYPE&& type) {
|
||||||
builtin::InterpolationType type,
|
return create<ast::InterpolateAttribute>(source, Expr(std::forward<TYPE>(type)), nullptr);
|
||||||
builtin::InterpolationSampling sampling = builtin::InterpolationSampling::kUndefined) {
|
|
||||||
return create<ast::InterpolateAttribute>(source, type, sampling);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::InterpolateAttribute
|
/// Creates an ast::InterpolateAttribute
|
||||||
/// @param type the interpolation type
|
/// @param type the interpolation type
|
||||||
/// @param sampling the interpolation sampling
|
/// @param sampling the interpolation sampling
|
||||||
/// @returns the interpolate attribute pointer
|
/// @returns the interpolate attribute pointer
|
||||||
const ast::InterpolateAttribute* Interpolate(
|
template <typename TYPE, typename SAMPLING, typename = DisableIfSource<TYPE>>
|
||||||
builtin::InterpolationType type,
|
const ast::InterpolateAttribute* Interpolate(TYPE&& type, SAMPLING&& sampling) {
|
||||||
builtin::InterpolationSampling sampling = builtin::InterpolationSampling::kUndefined) {
|
return Interpolate(source_, std::forward<TYPE>(type), std::forward<SAMPLING>(sampling));
|
||||||
return create<ast::InterpolateAttribute>(source_, type, sampling);
|
}
|
||||||
|
|
||||||
|
/// Creates an ast::InterpolateAttribute
|
||||||
|
/// @param source the source information
|
||||||
|
/// @param type the interpolation type
|
||||||
|
/// @param sampling the interpolation sampling
|
||||||
|
/// @returns the interpolate attribute pointer
|
||||||
|
template <typename TYPE, typename SAMPLING>
|
||||||
|
const ast::InterpolateAttribute* Interpolate(const Source& source,
|
||||||
|
TYPE&& type,
|
||||||
|
SAMPLING&& sampling) {
|
||||||
|
if constexpr (std::is_same_v<std::decay_t<SAMPLING>, builtin::InterpolationSampling>) {
|
||||||
|
if (sampling == builtin::InterpolationSampling::kUndefined) {
|
||||||
|
return create<ast::InterpolateAttribute>(source, Expr(std::forward<TYPE>(type)),
|
||||||
|
nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return create<ast::InterpolateAttribute>(source, Expr(std::forward<TYPE>(type)),
|
||||||
|
Expr(std::forward<SAMPLING>(sampling)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an ast::InterpolateAttribute using flat interpolation
|
/// Creates an ast::InterpolateAttribute using flat interpolation
|
||||||
|
@ -1821,7 +1821,7 @@ bool ParserImpl::ConvertPipelineDecorations(const Type* store_type,
|
|||||||
sampling == builtin::InterpolationSampling::kUndefined) {
|
sampling == builtin::InterpolationSampling::kUndefined) {
|
||||||
// This is the default. Don't add a decoration.
|
// This is the default. Don't add a decoration.
|
||||||
} else {
|
} else {
|
||||||
attributes.Add(create<ast::InterpolateAttribute>(type, sampling));
|
attributes.Add(builder_.Interpolate(type, sampling));
|
||||||
}
|
}
|
||||||
|
|
||||||
return success();
|
return success();
|
||||||
|
@ -1103,24 +1103,6 @@ Expect<const ast::Parameter*> ParserImpl::expect_param() {
|
|||||||
std::move(attrs.value)); // attributes
|
std::move(attrs.value)); // attributes
|
||||||
}
|
}
|
||||||
|
|
||||||
// interpolation_sample_name
|
|
||||||
// : 'center'
|
|
||||||
// | 'centroid'
|
|
||||||
// | 'sample'
|
|
||||||
Expect<builtin::InterpolationSampling> ParserImpl::expect_interpolation_sample_name() {
|
|
||||||
return expect_enum("interpolation sampling", builtin::ParseInterpolationSampling,
|
|
||||||
builtin::kInterpolationSamplingStrings);
|
|
||||||
}
|
|
||||||
|
|
||||||
// interpolation_type_name
|
|
||||||
// : 'perspective'
|
|
||||||
// | 'linear'
|
|
||||||
// | 'flat'
|
|
||||||
Expect<builtin::InterpolationType> ParserImpl::expect_interpolation_type_name() {
|
|
||||||
return expect_enum("interpolation type", builtin::ParseInterpolationType,
|
|
||||||
builtin::kInterpolationTypeStrings);
|
|
||||||
}
|
|
||||||
|
|
||||||
// compound_statement
|
// compound_statement
|
||||||
// : attribute* BRACE_LEFT statement* BRACE_RIGHT
|
// : attribute* BRACE_LEFT statement* BRACE_RIGHT
|
||||||
Expect<ast::BlockStatement*> ParserImpl::expect_compound_statement(std::string_view use) {
|
Expect<ast::BlockStatement*> ParserImpl::expect_compound_statement(std::string_view use) {
|
||||||
@ -3061,15 +3043,15 @@ Maybe<const ast::Attribute*> ParserImpl::attribute() {
|
|||||||
|
|
||||||
if (t == "interpolate") {
|
if (t == "interpolate") {
|
||||||
return expect_paren_block("interpolate attribute", [&]() -> Result {
|
return expect_paren_block("interpolate attribute", [&]() -> Result {
|
||||||
auto type = expect_interpolation_type_name();
|
auto type = expect_expression("interpolation type");
|
||||||
if (type.errored) {
|
if (type.errored) {
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
|
|
||||||
builtin::InterpolationSampling sampling = builtin::InterpolationSampling::kUndefined;
|
const ast::Expression* sampling = nullptr;
|
||||||
if (match(Token::Type::kComma)) {
|
if (match(Token::Type::kComma)) {
|
||||||
if (!peek_is(Token::Type::kParenRight)) {
|
if (!peek_is(Token::Type::kParenRight)) {
|
||||||
auto sample = expect_interpolation_sample_name();
|
auto sample = expect_expression("interpolation sampling");
|
||||||
if (sample.errored) {
|
if (sample.errored) {
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
|
@ -454,14 +454,6 @@ class ParserImpl {
|
|||||||
/// not match a stage name.
|
/// not match a stage name.
|
||||||
/// @returns the pipeline stage.
|
/// @returns the pipeline stage.
|
||||||
Expect<ast::PipelineStage> expect_pipeline_stage();
|
Expect<ast::PipelineStage> expect_pipeline_stage();
|
||||||
/// Parses an interpolation sample name identifier, erroring if the next token does not match a
|
|
||||||
/// valid sample name.
|
|
||||||
/// @returns the parsed sample name.
|
|
||||||
Expect<builtin::InterpolationSampling> expect_interpolation_sample_name();
|
|
||||||
/// Parses an interpolation type name identifier, erroring if the next token does not match a
|
|
||||||
/// value type name.
|
|
||||||
/// @returns the parsed type name
|
|
||||||
Expect<builtin::InterpolationType> expect_interpolation_type_name();
|
|
||||||
/// Parses a `compound_statement` grammar element, erroring on parse failure.
|
/// Parses a `compound_statement` grammar element, erroring on parse failure.
|
||||||
/// @param use a description of what was being parsed if an error was raised
|
/// @param use a description of what was being parsed if an error was raised
|
||||||
/// @returns the parsed statements
|
/// @returns the parsed statements
|
||||||
|
@ -308,8 +308,8 @@ TEST_F(ParserImplTest, Attribute_Interpolate_Flat) {
|
|||||||
ASSERT_TRUE(var_attr->Is<ast::InterpolateAttribute>());
|
ASSERT_TRUE(var_attr->Is<ast::InterpolateAttribute>());
|
||||||
|
|
||||||
auto* interp = var_attr->As<ast::InterpolateAttribute>();
|
auto* interp = var_attr->As<ast::InterpolateAttribute>();
|
||||||
EXPECT_EQ(interp->type, builtin::InterpolationType::kFlat);
|
ast::CheckIdentifier(p->builder().Symbols(), interp->type, "flat");
|
||||||
EXPECT_EQ(interp->sampling, builtin::InterpolationSampling::kUndefined);
|
EXPECT_EQ(interp->sampling, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, Attribute_Interpolate_Single_TrailingComma) {
|
TEST_F(ParserImplTest, Attribute_Interpolate_Single_TrailingComma) {
|
||||||
@ -324,8 +324,8 @@ TEST_F(ParserImplTest, Attribute_Interpolate_Single_TrailingComma) {
|
|||||||
ASSERT_TRUE(var_attr->Is<ast::InterpolateAttribute>());
|
ASSERT_TRUE(var_attr->Is<ast::InterpolateAttribute>());
|
||||||
|
|
||||||
auto* interp = var_attr->As<ast::InterpolateAttribute>();
|
auto* interp = var_attr->As<ast::InterpolateAttribute>();
|
||||||
EXPECT_EQ(interp->type, builtin::InterpolationType::kFlat);
|
ast::CheckIdentifier(p->builder().Symbols(), interp->type, "flat");
|
||||||
EXPECT_EQ(interp->sampling, builtin::InterpolationSampling::kUndefined);
|
EXPECT_EQ(interp->sampling, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, Attribute_Interpolate_Single_DoubleTrailingComma) {
|
TEST_F(ParserImplTest, Attribute_Interpolate_Single_DoubleTrailingComma) {
|
||||||
@ -335,8 +335,7 @@ TEST_F(ParserImplTest, Attribute_Interpolate_Single_DoubleTrailingComma) {
|
|||||||
EXPECT_TRUE(attr.errored);
|
EXPECT_TRUE(attr.errored);
|
||||||
EXPECT_EQ(attr.value, nullptr);
|
EXPECT_EQ(attr.value, nullptr);
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
EXPECT_EQ(p->error(), R"(1:18: expected interpolation sampling
|
EXPECT_EQ(p->error(), R"(1:18: expected expression for interpolation sampling)");
|
||||||
Possible values: 'center', 'centroid', 'sample')");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, Attribute_Interpolate_Perspective_Center) {
|
TEST_F(ParserImplTest, Attribute_Interpolate_Perspective_Center) {
|
||||||
@ -351,8 +350,8 @@ TEST_F(ParserImplTest, Attribute_Interpolate_Perspective_Center) {
|
|||||||
ASSERT_TRUE(var_attr->Is<ast::InterpolateAttribute>());
|
ASSERT_TRUE(var_attr->Is<ast::InterpolateAttribute>());
|
||||||
|
|
||||||
auto* interp = var_attr->As<ast::InterpolateAttribute>();
|
auto* interp = var_attr->As<ast::InterpolateAttribute>();
|
||||||
EXPECT_EQ(interp->type, builtin::InterpolationType::kPerspective);
|
ast::CheckIdentifier(p->builder().Symbols(), interp->type, "perspective");
|
||||||
EXPECT_EQ(interp->sampling, builtin::InterpolationSampling::kCenter);
|
ast::CheckIdentifier(p->builder().Symbols(), interp->sampling, "center");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, Attribute_Interpolate_Double_TrailingComma) {
|
TEST_F(ParserImplTest, Attribute_Interpolate_Double_TrailingComma) {
|
||||||
@ -367,8 +366,8 @@ TEST_F(ParserImplTest, Attribute_Interpolate_Double_TrailingComma) {
|
|||||||
ASSERT_TRUE(var_attr->Is<ast::InterpolateAttribute>());
|
ASSERT_TRUE(var_attr->Is<ast::InterpolateAttribute>());
|
||||||
|
|
||||||
auto* interp = var_attr->As<ast::InterpolateAttribute>();
|
auto* interp = var_attr->As<ast::InterpolateAttribute>();
|
||||||
EXPECT_EQ(interp->type, builtin::InterpolationType::kPerspective);
|
ast::CheckIdentifier(p->builder().Symbols(), interp->type, "perspective");
|
||||||
EXPECT_EQ(interp->sampling, builtin::InterpolationSampling::kCenter);
|
ast::CheckIdentifier(p->builder().Symbols(), interp->sampling, "center");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, Attribute_Interpolate_Perspective_Centroid) {
|
TEST_F(ParserImplTest, Attribute_Interpolate_Perspective_Centroid) {
|
||||||
@ -383,8 +382,8 @@ TEST_F(ParserImplTest, Attribute_Interpolate_Perspective_Centroid) {
|
|||||||
ASSERT_TRUE(var_attr->Is<ast::InterpolateAttribute>());
|
ASSERT_TRUE(var_attr->Is<ast::InterpolateAttribute>());
|
||||||
|
|
||||||
auto* interp = var_attr->As<ast::InterpolateAttribute>();
|
auto* interp = var_attr->As<ast::InterpolateAttribute>();
|
||||||
EXPECT_EQ(interp->type, builtin::InterpolationType::kPerspective);
|
ast::CheckIdentifier(p->builder().Symbols(), interp->type, "perspective");
|
||||||
EXPECT_EQ(interp->sampling, builtin::InterpolationSampling::kCentroid);
|
ast::CheckIdentifier(p->builder().Symbols(), interp->sampling, "centroid");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, Attribute_Interpolate_Linear_Sample) {
|
TEST_F(ParserImplTest, Attribute_Interpolate_Linear_Sample) {
|
||||||
@ -399,8 +398,8 @@ TEST_F(ParserImplTest, Attribute_Interpolate_Linear_Sample) {
|
|||||||
ASSERT_TRUE(var_attr->Is<ast::InterpolateAttribute>());
|
ASSERT_TRUE(var_attr->Is<ast::InterpolateAttribute>());
|
||||||
|
|
||||||
auto* interp = var_attr->As<ast::InterpolateAttribute>();
|
auto* interp = var_attr->As<ast::InterpolateAttribute>();
|
||||||
EXPECT_EQ(interp->type, builtin::InterpolationType::kLinear);
|
ast::CheckIdentifier(p->builder().Symbols(), interp->type, "linear");
|
||||||
EXPECT_EQ(interp->sampling, builtin::InterpolationSampling::kSample);
|
ast::CheckIdentifier(p->builder().Symbols(), interp->sampling, "sample");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, Attribute_Interpolate_MissingLeftParen) {
|
TEST_F(ParserImplTest, Attribute_Interpolate_MissingLeftParen) {
|
||||||
@ -430,31 +429,7 @@ TEST_F(ParserImplTest, Attribute_Interpolate_MissingFirstValue) {
|
|||||||
EXPECT_TRUE(attr.errored);
|
EXPECT_TRUE(attr.errored);
|
||||||
EXPECT_EQ(attr.value, nullptr);
|
EXPECT_EQ(attr.value, nullptr);
|
||||||
EXPECT_TRUE(p->has_error());
|
EXPECT_TRUE(p->has_error());
|
||||||
EXPECT_EQ(p->error(), R"(1:13: expected interpolation type
|
EXPECT_EQ(p->error(), R"(1:13: expected expression for interpolation type)");
|
||||||
Possible values: 'flat', 'linear', 'perspective')");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ParserImplTest, Attribute_Interpolate_InvalidFirstValue) {
|
|
||||||
auto p = parser("interpolate(other_thingy)");
|
|
||||||
auto attr = p->attribute();
|
|
||||||
EXPECT_FALSE(attr.matched);
|
|
||||||
EXPECT_TRUE(attr.errored);
|
|
||||||
EXPECT_EQ(attr.value, nullptr);
|
|
||||||
EXPECT_TRUE(p->has_error());
|
|
||||||
EXPECT_EQ(p->error(), R"(1:13: expected interpolation type
|
|
||||||
Possible values: 'flat', 'linear', 'perspective')");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ParserImplTest, Attribute_Interpolate_InvalidSecondValue) {
|
|
||||||
auto p = parser("interpolate(perspective, nope)");
|
|
||||||
auto attr = p->attribute();
|
|
||||||
EXPECT_FALSE(attr.matched);
|
|
||||||
EXPECT_TRUE(attr.errored);
|
|
||||||
EXPECT_EQ(attr.value, nullptr);
|
|
||||||
EXPECT_TRUE(p->has_error());
|
|
||||||
EXPECT_EQ(p->error(), R"(1:26: expected interpolation sampling
|
|
||||||
Did you mean 'sample'?
|
|
||||||
Possible values: 'center', 'centroid', 'sample')");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, Attribute_Binding) {
|
TEST_F(ParserImplTest, Attribute_Binding) {
|
||||||
|
@ -1649,8 +1649,7 @@ TEST_F(InterpolateTest, MissingLocationAttribute_Parameter) {
|
|||||||
Param("a", ty.vec4<f32>(),
|
Param("a", ty.vec4<f32>(),
|
||||||
utils::Vector{
|
utils::Vector{
|
||||||
Builtin(builtin::BuiltinValue::kPosition),
|
Builtin(builtin::BuiltinValue::kPosition),
|
||||||
Interpolate(Source{{12, 34}}, builtin::InterpolationType::kFlat,
|
Interpolate(Source{{12, 34}}, builtin::InterpolationType::kFlat),
|
||||||
builtin::InterpolationSampling::kUndefined),
|
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
ty.void_(), utils::Empty,
|
ty.void_(), utils::Empty,
|
||||||
@ -1673,8 +1672,7 @@ TEST_F(InterpolateTest, MissingLocationAttribute_ReturnType) {
|
|||||||
},
|
},
|
||||||
utils::Vector{
|
utils::Vector{
|
||||||
Builtin(builtin::BuiltinValue::kPosition),
|
Builtin(builtin::BuiltinValue::kPosition),
|
||||||
Interpolate(Source{{12, 34}}, builtin::InterpolationType::kFlat,
|
Interpolate(Source{{12, 34}}, builtin::InterpolationType::kFlat),
|
||||||
builtin::InterpolationSampling::kUndefined),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
@ -1687,8 +1685,7 @@ TEST_F(InterpolateTest, MissingLocationAttribute_Struct) {
|
|||||||
"S",
|
"S",
|
||||||
utils::Vector{
|
utils::Vector{
|
||||||
Member("a", ty.f32(),
|
Member("a", ty.f32(),
|
||||||
utils::Vector{Interpolate(Source{{12, 34}}, builtin::InterpolationType::kFlat,
|
utils::Vector{Interpolate(Source{{12, 34}}, builtin::InterpolationType::kFlat)}),
|
||||||
builtin::InterpolationSampling::kUndefined)}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
@ -438,6 +438,11 @@ class DependencyScanner {
|
|||||||
TraverseValueExpression(id->expr);
|
TraverseValueExpression(id->expr);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
[&](const ast::InterpolateAttribute* interpolate) {
|
||||||
|
TraverseExpression(interpolate->type, "interpolation type", "references");
|
||||||
|
TraverseExpression(interpolate->sampling, "interpolation sampling", "references");
|
||||||
|
return true;
|
||||||
|
},
|
||||||
[&](const ast::LocationAttribute* loc) {
|
[&](const ast::LocationAttribute* loc) {
|
||||||
TraverseValueExpression(loc->expr);
|
TraverseValueExpression(loc->expr);
|
||||||
return true;
|
return true;
|
||||||
@ -505,6 +510,16 @@ class DependencyScanner {
|
|||||||
graph_.resolved_identifiers.Add(from, ResolvedIdentifier(access));
|
graph_.resolved_identifiers.Add(from, ResolvedIdentifier(access));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (auto i_type = builtin::ParseInterpolationType(s);
|
||||||
|
i_type != builtin::InterpolationType::kUndefined) {
|
||||||
|
graph_.resolved_identifiers.Add(from, ResolvedIdentifier(i_type));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (auto i_smpl = builtin::ParseInterpolationSampling(s);
|
||||||
|
i_smpl != builtin::InterpolationSampling::kUndefined) {
|
||||||
|
graph_.resolved_identifiers.Add(from, ResolvedIdentifier(i_smpl));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
UnknownSymbol(to, from->source, use);
|
UnknownSymbol(to, from->source, use);
|
||||||
return;
|
return;
|
||||||
@ -884,6 +899,12 @@ std::string ResolvedIdentifier::String(const SymbolTable& symbols, diag::List& d
|
|||||||
if (auto addr = AddressSpace(); addr != builtin::AddressSpace::kUndefined) {
|
if (auto addr = AddressSpace(); addr != builtin::AddressSpace::kUndefined) {
|
||||||
return "address space '" + utils::ToString(addr) + "'";
|
return "address space '" + utils::ToString(addr) + "'";
|
||||||
}
|
}
|
||||||
|
if (auto type = InterpolationType(); type != builtin::InterpolationType::kUndefined) {
|
||||||
|
return "interpolation type '" + utils::ToString(type) + "'";
|
||||||
|
}
|
||||||
|
if (auto smpl = InterpolationSampling(); smpl != builtin::InterpolationSampling::kUndefined) {
|
||||||
|
return "interpolation sampling '" + utils::ToString(smpl) + "'";
|
||||||
|
}
|
||||||
if (auto fmt = TexelFormat(); fmt != builtin::TexelFormat::kUndefined) {
|
if (auto fmt = TexelFormat(); fmt != builtin::TexelFormat::kUndefined) {
|
||||||
return "texel format '" + utils::ToString(fmt) + "'";
|
return "texel format '" + utils::ToString(fmt) + "'";
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
#include "src/tint/builtin/access.h"
|
#include "src/tint/builtin/access.h"
|
||||||
#include "src/tint/builtin/builtin.h"
|
#include "src/tint/builtin/builtin.h"
|
||||||
#include "src/tint/builtin/builtin_value.h"
|
#include "src/tint/builtin/builtin_value.h"
|
||||||
|
#include "src/tint/builtin/interpolation_sampling.h"
|
||||||
|
#include "src/tint/builtin/interpolation_type.h"
|
||||||
#include "src/tint/builtin/texel_format.h"
|
#include "src/tint/builtin/texel_format.h"
|
||||||
#include "src/tint/diagnostic/diagnostic.h"
|
#include "src/tint/diagnostic/diagnostic.h"
|
||||||
#include "src/tint/sem/builtin_type.h"
|
#include "src/tint/sem/builtin_type.h"
|
||||||
@ -40,6 +42,8 @@ namespace tint::resolver {
|
|||||||
/// - builtin::AddressSpace
|
/// - builtin::AddressSpace
|
||||||
/// - builtin::Builtin
|
/// - builtin::Builtin
|
||||||
/// - builtin::BuiltinValue
|
/// - builtin::BuiltinValue
|
||||||
|
/// - builtin::InterpolationSampling
|
||||||
|
/// - builtin::InterpolationType
|
||||||
/// - builtin::TexelFormat
|
/// - builtin::TexelFormat
|
||||||
class ResolvedIdentifier {
|
class ResolvedIdentifier {
|
||||||
public:
|
public:
|
||||||
@ -106,6 +110,24 @@ class ResolvedIdentifier {
|
|||||||
return builtin::BuiltinValue::kUndefined;
|
return builtin::BuiltinValue::kUndefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @return the texel format if the ResolvedIdentifier holds type::InterpolationSampling,
|
||||||
|
/// otherwise type::InterpolationSampling::kUndefined
|
||||||
|
builtin::InterpolationSampling InterpolationSampling() const {
|
||||||
|
if (auto n = std::get_if<builtin::InterpolationSampling>(&value_)) {
|
||||||
|
return *n;
|
||||||
|
}
|
||||||
|
return builtin::InterpolationSampling::kUndefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @return the texel format if the ResolvedIdentifier holds type::InterpolationType,
|
||||||
|
/// otherwise type::InterpolationType::kUndefined
|
||||||
|
builtin::InterpolationType InterpolationType() const {
|
||||||
|
if (auto n = std::get_if<builtin::InterpolationType>(&value_)) {
|
||||||
|
return *n;
|
||||||
|
}
|
||||||
|
return builtin::InterpolationType::kUndefined;
|
||||||
|
}
|
||||||
|
|
||||||
/// @return the texel format if the ResolvedIdentifier holds type::TexelFormat, otherwise
|
/// @return the texel format if the ResolvedIdentifier holds type::TexelFormat, otherwise
|
||||||
/// type::TexelFormat::kUndefined
|
/// type::TexelFormat::kUndefined
|
||||||
builtin::TexelFormat TexelFormat() const {
|
builtin::TexelFormat TexelFormat() const {
|
||||||
@ -145,6 +167,8 @@ class ResolvedIdentifier {
|
|||||||
builtin::AddressSpace,
|
builtin::AddressSpace,
|
||||||
builtin::Builtin,
|
builtin::Builtin,
|
||||||
builtin::BuiltinValue,
|
builtin::BuiltinValue,
|
||||||
|
builtin::InterpolationSampling,
|
||||||
|
builtin::InterpolationType,
|
||||||
builtin::TexelFormat>
|
builtin::TexelFormat>
|
||||||
value_;
|
value_;
|
||||||
};
|
};
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "src/tint/resolver/dependency_graph.h"
|
#include "src/tint/resolver/dependency_graph.h"
|
||||||
#include "src/tint/resolver/resolver_test_helper.h"
|
#include "src/tint/resolver/resolver_test_helper.h"
|
||||||
#include "src/tint/type/texture_dimension.h"
|
#include "src/tint/type/texture_dimension.h"
|
||||||
|
#include "src/tint/utils/transform.h"
|
||||||
|
|
||||||
using namespace tint::number_suffixes; // NOLINT
|
using namespace tint::number_suffixes; // NOLINT
|
||||||
|
|
||||||
@ -139,6 +140,40 @@ enum class SymbolUseKind {
|
|||||||
WorkgroupSizeValue,
|
WorkgroupSizeValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static constexpr SymbolUseKind kAllUseKinds[] = {
|
||||||
|
SymbolUseKind::GlobalVarType,
|
||||||
|
SymbolUseKind::GlobalVarArrayElemType,
|
||||||
|
SymbolUseKind::GlobalVarArraySizeValue,
|
||||||
|
SymbolUseKind::GlobalVarVectorElemType,
|
||||||
|
SymbolUseKind::GlobalVarMatrixElemType,
|
||||||
|
SymbolUseKind::GlobalVarSampledTexElemType,
|
||||||
|
SymbolUseKind::GlobalVarMultisampledTexElemType,
|
||||||
|
SymbolUseKind::GlobalVarValue,
|
||||||
|
SymbolUseKind::GlobalConstType,
|
||||||
|
SymbolUseKind::GlobalConstArrayElemType,
|
||||||
|
SymbolUseKind::GlobalConstArraySizeValue,
|
||||||
|
SymbolUseKind::GlobalConstVectorElemType,
|
||||||
|
SymbolUseKind::GlobalConstMatrixElemType,
|
||||||
|
SymbolUseKind::GlobalConstValue,
|
||||||
|
SymbolUseKind::AliasType,
|
||||||
|
SymbolUseKind::StructMemberType,
|
||||||
|
SymbolUseKind::CallFunction,
|
||||||
|
SymbolUseKind::ParameterType,
|
||||||
|
SymbolUseKind::LocalVarType,
|
||||||
|
SymbolUseKind::LocalVarArrayElemType,
|
||||||
|
SymbolUseKind::LocalVarArraySizeValue,
|
||||||
|
SymbolUseKind::LocalVarVectorElemType,
|
||||||
|
SymbolUseKind::LocalVarMatrixElemType,
|
||||||
|
SymbolUseKind::LocalVarValue,
|
||||||
|
SymbolUseKind::LocalLetType,
|
||||||
|
SymbolUseKind::LocalLetValue,
|
||||||
|
SymbolUseKind::NestedLocalVarType,
|
||||||
|
SymbolUseKind::NestedLocalVarValue,
|
||||||
|
SymbolUseKind::NestedLocalLetType,
|
||||||
|
SymbolUseKind::NestedLocalLetValue,
|
||||||
|
SymbolUseKind::WorkgroupSizeValue,
|
||||||
|
};
|
||||||
|
|
||||||
static constexpr SymbolUseKind kTypeUseKinds[] = {
|
static constexpr SymbolUseKind kTypeUseKinds[] = {
|
||||||
SymbolUseKind::GlobalVarType,
|
SymbolUseKind::GlobalVarType,
|
||||||
SymbolUseKind::GlobalVarArrayElemType,
|
SymbolUseKind::GlobalVarArrayElemType,
|
||||||
@ -1178,51 +1213,6 @@ TEST_P(ResolverDependencyGraphResolveToBuiltinFunc, Resolve) {
|
|||||||
EXPECT_EQ(resolved->BuiltinFunction(), builtin) << resolved->String(Symbols(), Diagnostics());
|
EXPECT_EQ(resolved->BuiltinFunction(), builtin) << resolved->String(Symbols(), Diagnostics());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(ResolverDependencyGraphResolveToBuiltinFunc, ShadowedByGlobalVar) {
|
|
||||||
const auto use = std::get<0>(GetParam());
|
|
||||||
const auto builtin = std::get<1>(GetParam());
|
|
||||||
const auto symbol = Symbols().New(utils::ToString(builtin));
|
|
||||||
|
|
||||||
SymbolTestHelper helper(this);
|
|
||||||
auto* decl = helper.Add(SymbolDeclKind::GlobalVar, symbol);
|
|
||||||
auto* ident = helper.Add(use, symbol);
|
|
||||||
helper.Build();
|
|
||||||
|
|
||||||
auto resolved = Build().resolved_identifiers.Get(ident);
|
|
||||||
ASSERT_TRUE(resolved);
|
|
||||||
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(ResolverDependencyGraphResolveToBuiltinFunc, ShadowedByStruct) {
|
|
||||||
const auto use = std::get<0>(GetParam());
|
|
||||||
const auto builtin = std::get<1>(GetParam());
|
|
||||||
const auto symbol = Symbols().New(utils::ToString(builtin));
|
|
||||||
|
|
||||||
SymbolTestHelper helper(this);
|
|
||||||
auto* decl = helper.Add(SymbolDeclKind::Struct, symbol);
|
|
||||||
auto* ident = helper.Add(use, symbol);
|
|
||||||
helper.Build();
|
|
||||||
|
|
||||||
auto resolved = Build().resolved_identifiers.Get(ident);
|
|
||||||
ASSERT_TRUE(resolved);
|
|
||||||
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(ResolverDependencyGraphResolveToBuiltinFunc, ShadowedByFunc) {
|
|
||||||
const auto use = std::get<0>(GetParam());
|
|
||||||
const auto builtin = std::get<1>(GetParam());
|
|
||||||
const auto symbol = Symbols().New(utils::ToString(builtin));
|
|
||||||
|
|
||||||
SymbolTestHelper helper(this);
|
|
||||||
auto* decl = helper.Add(SymbolDeclKind::Function, symbol);
|
|
||||||
auto* ident = helper.Add(use, symbol);
|
|
||||||
helper.Build();
|
|
||||||
|
|
||||||
auto resolved = Build().resolved_identifiers.Get(ident);
|
|
||||||
ASSERT_TRUE(resolved);
|
|
||||||
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(Types,
|
INSTANTIATE_TEST_SUITE_P(Types,
|
||||||
ResolverDependencyGraphResolveToBuiltinFunc,
|
ResolverDependencyGraphResolveToBuiltinFunc,
|
||||||
testing::Combine(testing::ValuesIn(kTypeUseKinds),
|
testing::Combine(testing::ValuesIn(kTypeUseKinds),
|
||||||
@ -1263,56 +1253,6 @@ TEST_P(ResolverDependencyGraphResolveToBuiltinType, Resolve) {
|
|||||||
<< resolved->String(Symbols(), Diagnostics());
|
<< resolved->String(Symbols(), Diagnostics());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(ResolverDependencyGraphResolveToBuiltinType, ShadowedByGlobalVar) {
|
|
||||||
const auto use = std::get<0>(GetParam());
|
|
||||||
const std::string name = std::get<1>(GetParam());
|
|
||||||
const auto symbol = Symbols().New(name);
|
|
||||||
|
|
||||||
auto* decl =
|
|
||||||
GlobalVar(symbol, name == "i32" ? ty.u32() : ty.i32(), builtin::AddressSpace::kPrivate);
|
|
||||||
|
|
||||||
SymbolTestHelper helper(this);
|
|
||||||
auto* ident = helper.Add(use, symbol);
|
|
||||||
helper.Build();
|
|
||||||
|
|
||||||
auto resolved = Build().resolved_identifiers.Get(ident);
|
|
||||||
ASSERT_TRUE(resolved);
|
|
||||||
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(ResolverDependencyGraphResolveToBuiltinType, ShadowedByStruct) {
|
|
||||||
const auto use = std::get<0>(GetParam());
|
|
||||||
const std::string name = std::get<1>(GetParam());
|
|
||||||
const auto symbol = Symbols().New(name);
|
|
||||||
|
|
||||||
auto* decl = Structure(symbol, utils::Vector{
|
|
||||||
Member("m", name == "i32" ? ty.u32() : ty.i32()),
|
|
||||||
});
|
|
||||||
|
|
||||||
SymbolTestHelper helper(this);
|
|
||||||
auto* ident = helper.Add(use, symbol);
|
|
||||||
helper.Build();
|
|
||||||
|
|
||||||
auto resolved = Build().resolved_identifiers.Get(ident);
|
|
||||||
ASSERT_TRUE(resolved);
|
|
||||||
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(ResolverDependencyGraphResolveToBuiltinType, ShadowedByFunc) {
|
|
||||||
const auto use = std::get<0>(GetParam());
|
|
||||||
const auto name = std::get<1>(GetParam());
|
|
||||||
const auto symbol = Symbols().New(name);
|
|
||||||
|
|
||||||
SymbolTestHelper helper(this);
|
|
||||||
auto* decl = helper.Add(SymbolDeclKind::Function, symbol);
|
|
||||||
auto* ident = helper.Add(use, symbol);
|
|
||||||
helper.Build();
|
|
||||||
|
|
||||||
auto resolved = Build().resolved_identifiers.Get(ident);
|
|
||||||
ASSERT_TRUE(resolved);
|
|
||||||
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(Types,
|
INSTANTIATE_TEST_SUITE_P(Types,
|
||||||
ResolverDependencyGraphResolveToBuiltinType,
|
ResolverDependencyGraphResolveToBuiltinType,
|
||||||
testing::Combine(testing::ValuesIn(kTypeUseKinds),
|
testing::Combine(testing::ValuesIn(kTypeUseKinds),
|
||||||
@ -1353,51 +1293,6 @@ TEST_P(ResolverDependencyGraphResolveToAccess, Resolve) {
|
|||||||
<< resolved->String(Symbols(), Diagnostics());
|
<< resolved->String(Symbols(), Diagnostics());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(ResolverDependencyGraphResolveToAccess, ShadowedByGlobalVar) {
|
|
||||||
const auto use = std::get<0>(GetParam());
|
|
||||||
const auto builtin = std::get<1>(GetParam());
|
|
||||||
const auto symbol = Symbols().New(utils::ToString(builtin));
|
|
||||||
|
|
||||||
SymbolTestHelper helper(this);
|
|
||||||
auto* decl = helper.Add(SymbolDeclKind::GlobalVar, symbol);
|
|
||||||
auto* ident = helper.Add(use, symbol);
|
|
||||||
helper.Build();
|
|
||||||
|
|
||||||
auto resolved = Build().resolved_identifiers.Get(ident);
|
|
||||||
ASSERT_TRUE(resolved);
|
|
||||||
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(ResolverDependencyGraphResolveToAccess, ShadowedByStruct) {
|
|
||||||
const auto use = std::get<0>(GetParam());
|
|
||||||
const auto builtin = std::get<1>(GetParam());
|
|
||||||
const auto symbol = Symbols().New(utils::ToString(builtin));
|
|
||||||
|
|
||||||
SymbolTestHelper helper(this);
|
|
||||||
auto* decl = helper.Add(SymbolDeclKind::Struct, symbol);
|
|
||||||
auto* ident = helper.Add(use, symbol);
|
|
||||||
helper.Build();
|
|
||||||
|
|
||||||
auto resolved = Build().resolved_identifiers.Get(ident);
|
|
||||||
ASSERT_TRUE(resolved);
|
|
||||||
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(ResolverDependencyGraphResolveToAccess, ShadowedByFunc) {
|
|
||||||
const auto use = std::get<0>(GetParam());
|
|
||||||
const auto builtin = std::get<1>(GetParam());
|
|
||||||
const auto symbol = Symbols().New(utils::ToString(builtin));
|
|
||||||
|
|
||||||
SymbolTestHelper helper(this);
|
|
||||||
auto* decl = helper.Add(SymbolDeclKind::Function, symbol);
|
|
||||||
auto* ident = helper.Add(use, symbol);
|
|
||||||
helper.Build();
|
|
||||||
|
|
||||||
auto resolved = Build().resolved_identifiers.Get(ident);
|
|
||||||
ASSERT_TRUE(resolved);
|
|
||||||
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(Types,
|
INSTANTIATE_TEST_SUITE_P(Types,
|
||||||
ResolverDependencyGraphResolveToAccess,
|
ResolverDependencyGraphResolveToAccess,
|
||||||
testing::Combine(testing::ValuesIn(kTypeUseKinds),
|
testing::Combine(testing::ValuesIn(kTypeUseKinds),
|
||||||
@ -1438,51 +1333,6 @@ TEST_P(ResolverDependencyGraphResolveToAddressSpace, Resolve) {
|
|||||||
<< resolved->String(Symbols(), Diagnostics());
|
<< resolved->String(Symbols(), Diagnostics());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(ResolverDependencyGraphResolveToAddressSpace, ShadowedByGlobalConst) {
|
|
||||||
const auto use = std::get<0>(GetParam());
|
|
||||||
const auto builtin = std::get<1>(GetParam());
|
|
||||||
const auto symbol = Symbols().New(utils::ToString(builtin));
|
|
||||||
|
|
||||||
SymbolTestHelper helper(this);
|
|
||||||
auto* decl = helper.Add(SymbolDeclKind::GlobalConst, symbol);
|
|
||||||
auto* ident = helper.Add(use, symbol);
|
|
||||||
helper.Build();
|
|
||||||
|
|
||||||
auto resolved = Build().resolved_identifiers.Get(ident);
|
|
||||||
ASSERT_TRUE(resolved);
|
|
||||||
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(ResolverDependencyGraphResolveToAddressSpace, ShadowedByStruct) {
|
|
||||||
const auto use = std::get<0>(GetParam());
|
|
||||||
const auto builtin = std::get<1>(GetParam());
|
|
||||||
const auto symbol = Symbols().New(utils::ToString(builtin));
|
|
||||||
|
|
||||||
SymbolTestHelper helper(this);
|
|
||||||
auto* decl = helper.Add(SymbolDeclKind::Struct, symbol);
|
|
||||||
auto* ident = helper.Add(use, symbol);
|
|
||||||
helper.Build();
|
|
||||||
|
|
||||||
auto resolved = Build().resolved_identifiers.Get(ident);
|
|
||||||
ASSERT_TRUE(resolved);
|
|
||||||
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(ResolverDependencyGraphResolveToAddressSpace, ShadowedByFunc) {
|
|
||||||
const auto use = std::get<0>(GetParam());
|
|
||||||
const auto builtin = std::get<1>(GetParam());
|
|
||||||
const auto symbol = Symbols().New(utils::ToString(builtin));
|
|
||||||
|
|
||||||
SymbolTestHelper helper(this);
|
|
||||||
auto* decl = helper.Add(SymbolDeclKind::Function, symbol);
|
|
||||||
auto* ident = helper.Add(use, symbol);
|
|
||||||
helper.Build();
|
|
||||||
|
|
||||||
auto resolved = Build().resolved_identifiers.Get(ident);
|
|
||||||
ASSERT_TRUE(resolved);
|
|
||||||
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(Types,
|
INSTANTIATE_TEST_SUITE_P(Types,
|
||||||
ResolverDependencyGraphResolveToAddressSpace,
|
ResolverDependencyGraphResolveToAddressSpace,
|
||||||
testing::Combine(testing::ValuesIn(kTypeUseKinds),
|
testing::Combine(testing::ValuesIn(kTypeUseKinds),
|
||||||
@ -1523,51 +1373,6 @@ TEST_P(ResolverDependencyGraphResolveToBuiltinValue, Resolve) {
|
|||||||
<< resolved->String(Symbols(), Diagnostics());
|
<< resolved->String(Symbols(), Diagnostics());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(ResolverDependencyGraphResolveToBuiltinValue, ShadowedByGlobalConst) {
|
|
||||||
const auto use = std::get<0>(GetParam());
|
|
||||||
const auto builtin = std::get<1>(GetParam());
|
|
||||||
const auto symbol = Symbols().New(utils::ToString(builtin));
|
|
||||||
|
|
||||||
SymbolTestHelper helper(this);
|
|
||||||
auto* decl = helper.Add(SymbolDeclKind::GlobalConst, symbol);
|
|
||||||
auto* ident = helper.Add(use, symbol);
|
|
||||||
helper.Build();
|
|
||||||
|
|
||||||
auto resolved = Build().resolved_identifiers.Get(ident);
|
|
||||||
ASSERT_TRUE(resolved);
|
|
||||||
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(ResolverDependencyGraphResolveToBuiltinValue, ShadowedByStruct) {
|
|
||||||
const auto use = std::get<0>(GetParam());
|
|
||||||
const auto builtin = std::get<1>(GetParam());
|
|
||||||
const auto symbol = Symbols().New(utils::ToString(builtin));
|
|
||||||
|
|
||||||
SymbolTestHelper helper(this);
|
|
||||||
auto* decl = helper.Add(SymbolDeclKind::Struct, symbol);
|
|
||||||
auto* ident = helper.Add(use, symbol);
|
|
||||||
helper.Build();
|
|
||||||
|
|
||||||
auto resolved = Build().resolved_identifiers.Get(ident);
|
|
||||||
ASSERT_TRUE(resolved);
|
|
||||||
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(ResolverDependencyGraphResolveToBuiltinValue, ShadowedByFunc) {
|
|
||||||
const auto use = std::get<0>(GetParam());
|
|
||||||
const auto builtin = std::get<1>(GetParam());
|
|
||||||
const auto symbol = Symbols().New(utils::ToString(builtin));
|
|
||||||
|
|
||||||
SymbolTestHelper helper(this);
|
|
||||||
auto* decl = helper.Add(SymbolDeclKind::Function, symbol);
|
|
||||||
auto* ident = helper.Add(use, symbol);
|
|
||||||
helper.Build();
|
|
||||||
|
|
||||||
auto resolved = Build().resolved_identifiers.Get(ident);
|
|
||||||
ASSERT_TRUE(resolved);
|
|
||||||
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(Types,
|
INSTANTIATE_TEST_SUITE_P(Types,
|
||||||
ResolverDependencyGraphResolveToBuiltinValue,
|
ResolverDependencyGraphResolveToBuiltinValue,
|
||||||
testing::Combine(testing::ValuesIn(kTypeUseKinds),
|
testing::Combine(testing::ValuesIn(kTypeUseKinds),
|
||||||
@ -1585,6 +1390,89 @@ INSTANTIATE_TEST_SUITE_P(Functions,
|
|||||||
|
|
||||||
} // namespace resolve_to_builtin_value
|
} // namespace resolve_to_builtin_value
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Resolve to builtin::InterpolationSampling tests
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
namespace resolve_to_interpolation_sampling {
|
||||||
|
|
||||||
|
using ResolverDependencyGraphResolveToInterpolationSampling =
|
||||||
|
ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, const char*>>;
|
||||||
|
|
||||||
|
TEST_P(ResolverDependencyGraphResolveToInterpolationSampling, Resolve) {
|
||||||
|
const auto use = std::get<0>(GetParam());
|
||||||
|
const auto name = std::get<1>(GetParam());
|
||||||
|
const auto symbol = Symbols().New(name);
|
||||||
|
|
||||||
|
SymbolTestHelper helper(this);
|
||||||
|
auto* ident = helper.Add(use, symbol);
|
||||||
|
helper.Build();
|
||||||
|
|
||||||
|
auto resolved = Build().resolved_identifiers.Get(ident);
|
||||||
|
ASSERT_TRUE(resolved);
|
||||||
|
EXPECT_EQ(resolved->InterpolationSampling(), builtin::ParseInterpolationSampling(name))
|
||||||
|
<< resolved->String(Symbols(), Diagnostics());
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(Types,
|
||||||
|
ResolverDependencyGraphResolveToInterpolationSampling,
|
||||||
|
testing::Combine(testing::ValuesIn(kTypeUseKinds),
|
||||||
|
testing::ValuesIn(builtin::kInterpolationTypeStrings)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(Values,
|
||||||
|
ResolverDependencyGraphResolveToInterpolationSampling,
|
||||||
|
testing::Combine(testing::ValuesIn(kValueUseKinds),
|
||||||
|
testing::ValuesIn(builtin::kInterpolationTypeStrings)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(Functions,
|
||||||
|
ResolverDependencyGraphResolveToInterpolationSampling,
|
||||||
|
testing::Combine(testing::ValuesIn(kFuncUseKinds),
|
||||||
|
testing::ValuesIn(builtin::kInterpolationTypeStrings)));
|
||||||
|
|
||||||
|
} // namespace resolve_to_interpolation_sampling
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Resolve to builtin::InterpolationType tests
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
namespace resolve_to_interpolation_sampling {
|
||||||
|
|
||||||
|
using ResolverDependencyGraphResolveToInterpolationType =
|
||||||
|
ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, const char*>>;
|
||||||
|
|
||||||
|
TEST_P(ResolverDependencyGraphResolveToInterpolationType, Resolve) {
|
||||||
|
const auto use = std::get<0>(GetParam());
|
||||||
|
const auto name = std::get<1>(GetParam());
|
||||||
|
const auto symbol = Symbols().New(name);
|
||||||
|
|
||||||
|
SymbolTestHelper helper(this);
|
||||||
|
auto* ident = helper.Add(use, symbol);
|
||||||
|
helper.Build();
|
||||||
|
|
||||||
|
auto resolved = Build().resolved_identifiers.Get(ident);
|
||||||
|
ASSERT_TRUE(resolved);
|
||||||
|
EXPECT_EQ(resolved->InterpolationType(), builtin::ParseInterpolationType(name))
|
||||||
|
<< resolved->String(Symbols(), Diagnostics());
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
Types,
|
||||||
|
ResolverDependencyGraphResolveToInterpolationType,
|
||||||
|
testing::Combine(testing::ValuesIn(kTypeUseKinds),
|
||||||
|
testing::ValuesIn(builtin::kInterpolationSamplingStrings)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
Values,
|
||||||
|
ResolverDependencyGraphResolveToInterpolationType,
|
||||||
|
testing::Combine(testing::ValuesIn(kValueUseKinds),
|
||||||
|
testing::ValuesIn(builtin::kInterpolationSamplingStrings)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
Functions,
|
||||||
|
ResolverDependencyGraphResolveToInterpolationType,
|
||||||
|
testing::Combine(testing::ValuesIn(kFuncUseKinds),
|
||||||
|
testing::ValuesIn(builtin::kInterpolationSamplingStrings)));
|
||||||
|
|
||||||
|
} // namespace resolve_to_interpolation_sampling
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Resolve to builtin::TexelFormat tests
|
// Resolve to builtin::TexelFormat tests
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -1608,51 +1496,6 @@ TEST_P(ResolverDependencyGraphResolveToTexelFormat, Resolve) {
|
|||||||
<< resolved->String(Symbols(), Diagnostics());
|
<< resolved->String(Symbols(), Diagnostics());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(ResolverDependencyGraphResolveToTexelFormat, ShadowedByGlobalVar) {
|
|
||||||
const auto use = std::get<0>(GetParam());
|
|
||||||
const auto builtin = std::get<1>(GetParam());
|
|
||||||
const auto symbol = Symbols().New(utils::ToString(builtin));
|
|
||||||
|
|
||||||
SymbolTestHelper helper(this);
|
|
||||||
auto* decl = helper.Add(SymbolDeclKind::GlobalVar, symbol);
|
|
||||||
auto* ident = helper.Add(use, symbol);
|
|
||||||
helper.Build();
|
|
||||||
|
|
||||||
auto resolved = Build().resolved_identifiers.Get(ident);
|
|
||||||
ASSERT_TRUE(resolved);
|
|
||||||
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(ResolverDependencyGraphResolveToTexelFormat, ShadowedByStruct) {
|
|
||||||
const auto use = std::get<0>(GetParam());
|
|
||||||
const auto builtin = std::get<1>(GetParam());
|
|
||||||
const auto symbol = Symbols().New(utils::ToString(builtin));
|
|
||||||
|
|
||||||
SymbolTestHelper helper(this);
|
|
||||||
auto* decl = helper.Add(SymbolDeclKind::Struct, symbol);
|
|
||||||
auto* ident = helper.Add(use, symbol);
|
|
||||||
helper.Build();
|
|
||||||
|
|
||||||
auto resolved = Build().resolved_identifiers.Get(ident);
|
|
||||||
ASSERT_TRUE(resolved);
|
|
||||||
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(ResolverDependencyGraphResolveToTexelFormat, ShadowedByFunc) {
|
|
||||||
const auto use = std::get<0>(GetParam());
|
|
||||||
const auto builtin = std::get<1>(GetParam());
|
|
||||||
const auto symbol = Symbols().New(utils::ToString(builtin));
|
|
||||||
|
|
||||||
SymbolTestHelper helper(this);
|
|
||||||
auto* decl = helper.Add(SymbolDeclKind::Function, symbol);
|
|
||||||
auto* ident = helper.Add(use, symbol);
|
|
||||||
helper.Build();
|
|
||||||
|
|
||||||
auto resolved = Build().resolved_identifiers.Get(ident);
|
|
||||||
ASSERT_TRUE(resolved);
|
|
||||||
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
|
||||||
}
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(Types,
|
INSTANTIATE_TEST_SUITE_P(Types,
|
||||||
ResolverDependencyGraphResolveToTexelFormat,
|
ResolverDependencyGraphResolveToTexelFormat,
|
||||||
testing::Combine(testing::ValuesIn(kTypeUseKinds),
|
testing::Combine(testing::ValuesIn(kTypeUseKinds),
|
||||||
@ -1675,10 +1518,10 @@ INSTANTIATE_TEST_SUITE_P(Functions,
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
namespace shadowing {
|
namespace shadowing {
|
||||||
|
|
||||||
using ResolverDependencyGraphShadowTest =
|
using ResolverDependencyGraphShadowScopeTest =
|
||||||
ResolverDependencyGraphTestWithParam<std::tuple<SymbolDeclKind, SymbolDeclKind>>;
|
ResolverDependencyGraphTestWithParam<std::tuple<SymbolDeclKind, SymbolDeclKind>>;
|
||||||
|
|
||||||
TEST_P(ResolverDependencyGraphShadowTest, Test) {
|
TEST_P(ResolverDependencyGraphShadowScopeTest, Test) {
|
||||||
const Symbol symbol = Sym("SYMBOL");
|
const Symbol symbol = Sym("SYMBOL");
|
||||||
const auto outer_kind = std::get<0>(GetParam());
|
const auto outer_kind = std::get<0>(GetParam());
|
||||||
const auto inner_kind = std::get<1>(GetParam());
|
const auto inner_kind = std::get<1>(GetParam());
|
||||||
@ -1701,18 +1544,107 @@ TEST_P(ResolverDependencyGraphShadowTest, Test) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(LocalShadowGlobal,
|
INSTANTIATE_TEST_SUITE_P(LocalShadowGlobal,
|
||||||
ResolverDependencyGraphShadowTest,
|
ResolverDependencyGraphShadowScopeTest,
|
||||||
testing::Combine(testing::ValuesIn(kGlobalDeclKinds),
|
testing::Combine(testing::ValuesIn(kGlobalDeclKinds),
|
||||||
testing::ValuesIn(kLocalDeclKinds)));
|
testing::ValuesIn(kLocalDeclKinds)));
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(NestedLocalShadowLocal,
|
INSTANTIATE_TEST_SUITE_P(NestedLocalShadowLocal,
|
||||||
ResolverDependencyGraphShadowTest,
|
ResolverDependencyGraphShadowScopeTest,
|
||||||
testing::Combine(testing::Values(SymbolDeclKind::Parameter,
|
testing::Combine(testing::Values(SymbolDeclKind::Parameter,
|
||||||
SymbolDeclKind::LocalVar,
|
SymbolDeclKind::LocalVar,
|
||||||
SymbolDeclKind::LocalLet),
|
SymbolDeclKind::LocalLet),
|
||||||
testing::Values(SymbolDeclKind::NestedLocalVar,
|
testing::Values(SymbolDeclKind::NestedLocalVar,
|
||||||
SymbolDeclKind::NestedLocalLet)));
|
SymbolDeclKind::NestedLocalLet)));
|
||||||
|
|
||||||
|
using ResolverDependencyGraphShadowKindTest =
|
||||||
|
ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, const char*>>;
|
||||||
|
|
||||||
|
TEST_P(ResolverDependencyGraphShadowKindTest, ShadowedByGlobalVar) {
|
||||||
|
const auto use = std::get<0>(GetParam());
|
||||||
|
const std::string_view name = std::get<1>(GetParam());
|
||||||
|
const auto symbol = Symbols().New(utils::ToString(name));
|
||||||
|
|
||||||
|
SymbolTestHelper helper(this);
|
||||||
|
auto* decl = GlobalVar(
|
||||||
|
symbol, //
|
||||||
|
name == "i32" ? ty.u32() : ty.i32(),
|
||||||
|
name == "private" ? builtin::AddressSpace::kWorkgroup : builtin::AddressSpace::kPrivate);
|
||||||
|
auto* ident = helper.Add(use, symbol);
|
||||||
|
helper.Build();
|
||||||
|
|
||||||
|
auto resolved = Build().resolved_identifiers.Get(ident);
|
||||||
|
ASSERT_TRUE(resolved);
|
||||||
|
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(ResolverDependencyGraphShadowKindTest, ShadowedByStruct) {
|
||||||
|
const auto use = std::get<0>(GetParam());
|
||||||
|
const std::string_view name = std::get<1>(GetParam());
|
||||||
|
const auto symbol = Symbols().New(utils::ToString(name));
|
||||||
|
|
||||||
|
SymbolTestHelper helper(this);
|
||||||
|
auto* decl = Structure(symbol, utils::Vector{
|
||||||
|
Member("m", name == "i32" ? ty.u32() : ty.i32()),
|
||||||
|
});
|
||||||
|
auto* ident = helper.Add(use, symbol);
|
||||||
|
helper.Build();
|
||||||
|
|
||||||
|
auto resolved = Build().resolved_identifiers.Get(ident);
|
||||||
|
ASSERT_TRUE(resolved);
|
||||||
|
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(ResolverDependencyGraphShadowKindTest, ShadowedByFunc) {
|
||||||
|
const auto use = std::get<0>(GetParam());
|
||||||
|
const auto name = std::get<1>(GetParam());
|
||||||
|
const auto symbol = Symbols().New(utils::ToString(name));
|
||||||
|
|
||||||
|
SymbolTestHelper helper(this);
|
||||||
|
auto* decl = helper.Add(SymbolDeclKind::Function, symbol);
|
||||||
|
auto* ident = helper.Add(use, symbol);
|
||||||
|
helper.Build();
|
||||||
|
|
||||||
|
auto resolved = Build().resolved_identifiers.Get(ident);
|
||||||
|
ASSERT_TRUE(resolved);
|
||||||
|
EXPECT_EQ(resolved->Node(), decl) << resolved->String(Symbols(), Diagnostics());
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(Access,
|
||||||
|
ResolverDependencyGraphShadowKindTest,
|
||||||
|
testing::Combine(testing::ValuesIn(kAllUseKinds),
|
||||||
|
testing::ValuesIn(builtin::kAccessStrings)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(AddressSpace,
|
||||||
|
ResolverDependencyGraphShadowKindTest,
|
||||||
|
testing::Combine(testing::ValuesIn(kAllUseKinds),
|
||||||
|
testing::ValuesIn(builtin::kAddressSpaceStrings)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(BuiltinType,
|
||||||
|
ResolverDependencyGraphShadowKindTest,
|
||||||
|
testing::Combine(testing::ValuesIn(kAllUseKinds),
|
||||||
|
testing::ValuesIn(builtin::kBuiltinStrings)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(BuiltinFunction,
|
||||||
|
ResolverDependencyGraphShadowKindTest,
|
||||||
|
testing::Combine(testing::ValuesIn(kAllUseKinds),
|
||||||
|
testing::ValuesIn(builtin::kBuiltinStrings)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
InterpolationSampling,
|
||||||
|
ResolverDependencyGraphShadowKindTest,
|
||||||
|
testing::Combine(testing::ValuesIn(kAllUseKinds),
|
||||||
|
testing::ValuesIn(builtin::kInterpolationSamplingStrings)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(InterpolationType,
|
||||||
|
ResolverDependencyGraphShadowKindTest,
|
||||||
|
testing::Combine(testing::ValuesIn(kAllUseKinds),
|
||||||
|
testing::ValuesIn(builtin::kInterpolationTypeStrings)));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(TexelFormat,
|
||||||
|
ResolverDependencyGraphShadowKindTest,
|
||||||
|
testing::Combine(testing::ValuesIn(kAllUseKinds),
|
||||||
|
testing::ValuesIn(builtin::kTexelFormatStrings)));
|
||||||
|
|
||||||
} // namespace shadowing
|
} // namespace shadowing
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -1753,6 +1685,7 @@ TEST_F(ResolverDependencyGraphTraversalTest, SymbolsReached) {
|
|||||||
std::string(__FILE__) + ":" + std::to_string(line) + ": " + kind});
|
std::string(__FILE__) + ":" + std::to_string(line) + ": " + kind});
|
||||||
return use;
|
return use;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define V add_use(value_decl, Expr(value_sym), __LINE__, "V()")
|
#define V add_use(value_decl, Expr(value_sym), __LINE__, "V()")
|
||||||
#define T add_use(type_decl, ty(type_sym), __LINE__, "T()")
|
#define T add_use(type_decl, ty(type_sym), __LINE__, "T()")
|
||||||
#define F add_use(func_decl, Ident(func_sym), __LINE__, "F()")
|
#define F add_use(func_decl, Ident(func_sym), __LINE__, "F()")
|
||||||
@ -1772,6 +1705,8 @@ TEST_F(ResolverDependencyGraphTraversalTest, SymbolsReached) {
|
|||||||
utils::Vector{
|
utils::Vector{
|
||||||
Location(V), // Parameter attributes
|
Location(V), // Parameter attributes
|
||||||
Builtin(V),
|
Builtin(V),
|
||||||
|
Interpolate(V),
|
||||||
|
Interpolate(V, V),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
T, // Return type
|
T, // Return type
|
||||||
|
@ -29,6 +29,8 @@ enum class Def {
|
|||||||
kBuiltinType,
|
kBuiltinType,
|
||||||
kBuiltinValue,
|
kBuiltinValue,
|
||||||
kFunction,
|
kFunction,
|
||||||
|
kInterpolationSampling,
|
||||||
|
kInterpolationType,
|
||||||
kStruct,
|
kStruct,
|
||||||
kTexelFormat,
|
kTexelFormat,
|
||||||
kTypeAlias,
|
kTypeAlias,
|
||||||
@ -49,6 +51,10 @@ std::ostream& operator<<(std::ostream& out, Def def) {
|
|||||||
return out << "Def::kBuiltinValue";
|
return out << "Def::kBuiltinValue";
|
||||||
case Def::kFunction:
|
case Def::kFunction:
|
||||||
return out << "Def::kFunction";
|
return out << "Def::kFunction";
|
||||||
|
case Def::kInterpolationSampling:
|
||||||
|
return out << "Def::kInterpolationSampling";
|
||||||
|
case Def::kInterpolationType:
|
||||||
|
return out << "Def::kInterpolationType";
|
||||||
case Def::kStruct:
|
case Def::kStruct:
|
||||||
return out << "Def::kStruct";
|
return out << "Def::kStruct";
|
||||||
case Def::kTexelFormat:
|
case Def::kTexelFormat:
|
||||||
@ -69,6 +75,8 @@ enum class Use {
|
|||||||
kCallExpr,
|
kCallExpr,
|
||||||
kCallStmt,
|
kCallStmt,
|
||||||
kFunctionReturnType,
|
kFunctionReturnType,
|
||||||
|
kInterpolationSampling,
|
||||||
|
kInterpolationType,
|
||||||
kMemberType,
|
kMemberType,
|
||||||
kTexelFormat,
|
kTexelFormat,
|
||||||
kValueExpression,
|
kValueExpression,
|
||||||
@ -92,6 +100,10 @@ std::ostream& operator<<(std::ostream& out, Use use) {
|
|||||||
return out << "Use::kCallStmt";
|
return out << "Use::kCallStmt";
|
||||||
case Use::kFunctionReturnType:
|
case Use::kFunctionReturnType:
|
||||||
return out << "Use::kFunctionReturnType";
|
return out << "Use::kFunctionReturnType";
|
||||||
|
case Use::kInterpolationSampling:
|
||||||
|
return out << "Use::kInterpolationSampling";
|
||||||
|
case Use::kInterpolationType:
|
||||||
|
return out << "Use::kInterpolationType";
|
||||||
case Use::kMemberType:
|
case Use::kMemberType:
|
||||||
return out << "Use::kMemberType";
|
return out << "Use::kMemberType";
|
||||||
case Use::kTexelFormat:
|
case Use::kTexelFormat:
|
||||||
@ -183,6 +195,28 @@ TEST_P(ResolverExpressionKindTest, Test) {
|
|||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Def::kInterpolationSampling: {
|
||||||
|
sym = Sym("center");
|
||||||
|
check_expr = [](const sem::Expression* expr) {
|
||||||
|
ASSERT_NE(expr, nullptr);
|
||||||
|
auto* enum_expr =
|
||||||
|
expr->As<sem::BuiltinEnumExpression<builtin::InterpolationSampling>>();
|
||||||
|
ASSERT_NE(enum_expr, nullptr);
|
||||||
|
EXPECT_EQ(enum_expr->Value(), builtin::InterpolationSampling::kCenter);
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Def::kInterpolationType: {
|
||||||
|
sym = Sym("linear");
|
||||||
|
check_expr = [](const sem::Expression* expr) {
|
||||||
|
ASSERT_NE(expr, nullptr);
|
||||||
|
auto* enum_expr =
|
||||||
|
expr->As<sem::BuiltinEnumExpression<builtin::InterpolationType>>();
|
||||||
|
ASSERT_NE(enum_expr, nullptr);
|
||||||
|
EXPECT_EQ(enum_expr->Value(), builtin::InterpolationType::kLinear);
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Def::kStruct: {
|
case Def::kStruct: {
|
||||||
auto* s = Structure(kDefSource, "STRUCT", utils::Vector{Member("m", ty.i32())});
|
auto* s = Structure(kDefSource, "STRUCT", utils::Vector{Member("m", ty.i32())});
|
||||||
sym = Sym("STRUCT");
|
sym = Sym("STRUCT");
|
||||||
@ -256,6 +290,26 @@ TEST_P(ResolverExpressionKindTest, Test) {
|
|||||||
case Use::kFunctionReturnType:
|
case Use::kFunctionReturnType:
|
||||||
Func("f", utils::Empty, ty(expr), Return(Call(sym)));
|
Func("f", utils::Empty, ty(expr), Return(Call(sym)));
|
||||||
break;
|
break;
|
||||||
|
case Use::kInterpolationSampling: {
|
||||||
|
Func("f",
|
||||||
|
utils::Vector{Param("p", ty.vec4<f32>(),
|
||||||
|
utils::Vector{
|
||||||
|
Location(0_a),
|
||||||
|
Interpolate(builtin::InterpolationType::kLinear, expr),
|
||||||
|
})},
|
||||||
|
ty.void_(), utils::Empty, utils::Vector{Stage(ast::PipelineStage::kFragment)});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Use::kInterpolationType: {
|
||||||
|
Func("f",
|
||||||
|
utils::Vector{Param("p", ty.vec4<f32>(),
|
||||||
|
utils::Vector{
|
||||||
|
Location(0_a),
|
||||||
|
Interpolate(expr, builtin::InterpolationSampling::kCenter),
|
||||||
|
})},
|
||||||
|
ty.void_(), utils::Empty, utils::Vector{Stage(ast::PipelineStage::kFragment)});
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Use::kMemberType:
|
case Use::kMemberType:
|
||||||
Structure("s", utils::Vector{Member("m", ty(expr))});
|
Structure("s", utils::Vector{Member("m", ty(expr))});
|
||||||
break;
|
break;
|
||||||
@ -296,6 +350,10 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
{Def::kAccess, Use::kCallExpr, R"(5:6 error: cannot use access 'write' as call target)"},
|
{Def::kAccess, Use::kCallExpr, R"(5:6 error: cannot use access 'write' as call target)"},
|
||||||
{Def::kAccess, Use::kCallStmt, R"(5:6 error: cannot use access 'write' as call target)"},
|
{Def::kAccess, Use::kCallStmt, R"(5:6 error: cannot use access 'write' as call target)"},
|
||||||
{Def::kAccess, Use::kFunctionReturnType, R"(5:6 error: cannot use access 'write' as type)"},
|
{Def::kAccess, Use::kFunctionReturnType, R"(5:6 error: cannot use access 'write' as type)"},
|
||||||
|
{Def::kAccess, Use::kInterpolationSampling,
|
||||||
|
R"(5:6 error: cannot use access 'write' as interpolation sampling)"},
|
||||||
|
{Def::kAccess, Use::kInterpolationType,
|
||||||
|
R"(5:6 error: cannot use access 'write' as interpolation type)"},
|
||||||
{Def::kAccess, Use::kMemberType, R"(5:6 error: cannot use access 'write' as type)"},
|
{Def::kAccess, Use::kMemberType, R"(5:6 error: cannot use access 'write' as type)"},
|
||||||
{Def::kAccess, Use::kTexelFormat,
|
{Def::kAccess, Use::kTexelFormat,
|
||||||
R"(5:6 error: cannot use access 'write' as texel format)"},
|
R"(5:6 error: cannot use access 'write' as texel format)"},
|
||||||
@ -316,6 +374,10 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
R"(5:6 error: cannot use address space 'workgroup' as call target)"},
|
R"(5:6 error: cannot use address space 'workgroup' as call target)"},
|
||||||
{Def::kAddressSpace, Use::kFunctionReturnType,
|
{Def::kAddressSpace, Use::kFunctionReturnType,
|
||||||
R"(5:6 error: cannot use address space 'workgroup' as type)"},
|
R"(5:6 error: cannot use address space 'workgroup' as type)"},
|
||||||
|
{Def::kAddressSpace, Use::kInterpolationSampling,
|
||||||
|
R"(5:6 error: cannot use address space 'workgroup' as interpolation sampling)"},
|
||||||
|
{Def::kAddressSpace, Use::kInterpolationType,
|
||||||
|
R"(5:6 error: cannot use address space 'workgroup' as interpolation type)"},
|
||||||
{Def::kAddressSpace, Use::kMemberType,
|
{Def::kAddressSpace, Use::kMemberType,
|
||||||
R"(5:6 error: cannot use address space 'workgroup' as type)"},
|
R"(5:6 error: cannot use address space 'workgroup' as type)"},
|
||||||
{Def::kAddressSpace, Use::kTexelFormat,
|
{Def::kAddressSpace, Use::kTexelFormat,
|
||||||
@ -338,6 +400,10 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
{Def::kBuiltinFunction, Use::kCallStmt, kPass},
|
{Def::kBuiltinFunction, Use::kCallStmt, kPass},
|
||||||
{Def::kBuiltinFunction, Use::kFunctionReturnType,
|
{Def::kBuiltinFunction, Use::kFunctionReturnType,
|
||||||
R"(7:8 error: missing '(' for builtin function call)"},
|
R"(7:8 error: missing '(' for builtin function call)"},
|
||||||
|
{Def::kBuiltinFunction, Use::kInterpolationSampling,
|
||||||
|
R"(7:8 error: missing '(' for builtin function call)"},
|
||||||
|
{Def::kBuiltinFunction, Use::kInterpolationType,
|
||||||
|
R"(7:8 error: missing '(' for builtin function call)"},
|
||||||
{Def::kBuiltinFunction, Use::kMemberType,
|
{Def::kBuiltinFunction, Use::kMemberType,
|
||||||
R"(7:8 error: missing '(' for builtin function call)"},
|
R"(7:8 error: missing '(' for builtin function call)"},
|
||||||
{Def::kBuiltinFunction, Use::kTexelFormat,
|
{Def::kBuiltinFunction, Use::kTexelFormat,
|
||||||
@ -359,6 +425,10 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
R"(5:6 error: cannot use type 'vec4<f32>' as builtin value)"},
|
R"(5:6 error: cannot use type 'vec4<f32>' as builtin value)"},
|
||||||
{Def::kBuiltinType, Use::kCallExpr, kPass},
|
{Def::kBuiltinType, Use::kCallExpr, kPass},
|
||||||
{Def::kBuiltinType, Use::kFunctionReturnType, kPass},
|
{Def::kBuiltinType, Use::kFunctionReturnType, kPass},
|
||||||
|
{Def::kBuiltinType, Use::kInterpolationSampling,
|
||||||
|
R"(5:6 error: cannot use type 'vec4<f32>' as interpolation sampling)"},
|
||||||
|
{Def::kBuiltinType, Use::kInterpolationType,
|
||||||
|
R"(5:6 error: cannot use type 'vec4<f32>' as interpolation type)"},
|
||||||
{Def::kBuiltinType, Use::kMemberType, kPass},
|
{Def::kBuiltinType, Use::kMemberType, kPass},
|
||||||
{Def::kBuiltinType, Use::kTexelFormat,
|
{Def::kBuiltinType, Use::kTexelFormat,
|
||||||
R"(5:6 error: cannot use type 'vec4<f32>' as texel format)"},
|
R"(5:6 error: cannot use type 'vec4<f32>' as texel format)"},
|
||||||
@ -383,6 +453,10 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
R"(5:6 error: cannot use builtin value 'position' as call target)"},
|
R"(5:6 error: cannot use builtin value 'position' as call target)"},
|
||||||
{Def::kBuiltinValue, Use::kFunctionReturnType,
|
{Def::kBuiltinValue, Use::kFunctionReturnType,
|
||||||
R"(5:6 error: cannot use builtin value 'position' as type)"},
|
R"(5:6 error: cannot use builtin value 'position' as type)"},
|
||||||
|
{Def::kBuiltinValue, Use::kInterpolationSampling,
|
||||||
|
R"(5:6 error: cannot use builtin value 'position' as interpolation sampling)"},
|
||||||
|
{Def::kBuiltinValue, Use::kInterpolationType,
|
||||||
|
R"(5:6 error: cannot use builtin value 'position' as interpolation type)"},
|
||||||
{Def::kBuiltinValue, Use::kMemberType,
|
{Def::kBuiltinValue, Use::kMemberType,
|
||||||
R"(5:6 error: cannot use builtin value 'position' as type)"},
|
R"(5:6 error: cannot use builtin value 'position' as type)"},
|
||||||
{Def::kBuiltinValue, Use::kTexelFormat,
|
{Def::kBuiltinValue, Use::kTexelFormat,
|
||||||
@ -408,6 +482,12 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
{Def::kFunction, Use::kCallStmt, kPass},
|
{Def::kFunction, Use::kCallStmt, kPass},
|
||||||
{Def::kFunction, Use::kFunctionReturnType,
|
{Def::kFunction, Use::kFunctionReturnType,
|
||||||
R"(5:6 error: cannot use function 'FUNCTION' as type
|
R"(5:6 error: cannot use function 'FUNCTION' as type
|
||||||
|
1:2 note: function 'FUNCTION' declared here)"},
|
||||||
|
{Def::kFunction, Use::kInterpolationSampling,
|
||||||
|
R"(5:6 error: cannot use function 'FUNCTION' as interpolation sampling
|
||||||
|
1:2 note: function 'FUNCTION' declared here)"},
|
||||||
|
{Def::kFunction, Use::kInterpolationType,
|
||||||
|
R"(5:6 error: cannot use function 'FUNCTION' as interpolation type
|
||||||
1:2 note: function 'FUNCTION' declared here)"},
|
1:2 note: function 'FUNCTION' declared here)"},
|
||||||
{Def::kFunction, Use::kMemberType,
|
{Def::kFunction, Use::kMemberType,
|
||||||
R"(5:6 error: cannot use function 'FUNCTION' as type
|
R"(5:6 error: cannot use function 'FUNCTION' as type
|
||||||
@ -424,6 +504,62 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
{Def::kFunction, Use::kUnaryOp, R"(5:6 error: cannot use function 'FUNCTION' as value
|
{Def::kFunction, Use::kUnaryOp, R"(5:6 error: cannot use function 'FUNCTION' as value
|
||||||
1:2 note: function 'FUNCTION' declared here)"},
|
1:2 note: function 'FUNCTION' declared here)"},
|
||||||
|
|
||||||
|
{Def::kInterpolationSampling, Use::kAccess,
|
||||||
|
R"(5:6 error: cannot use interpolation sampling 'center' as access)"},
|
||||||
|
{Def::kInterpolationSampling, Use::kAddressSpace,
|
||||||
|
R"(5:6 error: cannot use interpolation sampling 'center' as address space)"},
|
||||||
|
{Def::kInterpolationSampling, Use::kBinaryOp,
|
||||||
|
R"(5:6 error: cannot use interpolation sampling 'center' as value)"},
|
||||||
|
{Def::kInterpolationSampling, Use::kBuiltinValue,
|
||||||
|
R"(5:6 error: cannot use interpolation sampling 'center' as builtin value)"},
|
||||||
|
{Def::kInterpolationSampling, Use::kCallStmt,
|
||||||
|
R"(5:6 error: cannot use interpolation sampling 'center' as call target)"},
|
||||||
|
{Def::kInterpolationSampling, Use::kCallExpr,
|
||||||
|
R"(5:6 error: cannot use interpolation sampling 'center' as call target)"},
|
||||||
|
{Def::kInterpolationSampling, Use::kFunctionReturnType,
|
||||||
|
R"(5:6 error: cannot use interpolation sampling 'center' as type)"},
|
||||||
|
{Def::kInterpolationSampling, Use::kInterpolationSampling, kPass},
|
||||||
|
{Def::kInterpolationSampling, Use::kInterpolationType,
|
||||||
|
R"(5:6 error: cannot use interpolation sampling 'center' as interpolation type)"},
|
||||||
|
{Def::kInterpolationSampling, Use::kMemberType,
|
||||||
|
R"(5:6 error: cannot use interpolation sampling 'center' as type)"},
|
||||||
|
{Def::kInterpolationSampling, Use::kTexelFormat,
|
||||||
|
R"(5:6 error: cannot use interpolation sampling 'center' as texel format)"},
|
||||||
|
{Def::kInterpolationSampling, Use::kValueExpression,
|
||||||
|
R"(5:6 error: cannot use interpolation sampling 'center' as value)"},
|
||||||
|
{Def::kInterpolationSampling, Use::kVariableType,
|
||||||
|
R"(5:6 error: cannot use interpolation sampling 'center' as type)"},
|
||||||
|
{Def::kInterpolationSampling, Use::kUnaryOp,
|
||||||
|
R"(5:6 error: cannot use interpolation sampling 'center' as value)"},
|
||||||
|
|
||||||
|
{Def::kInterpolationType, Use::kAccess,
|
||||||
|
R"(5:6 error: cannot use interpolation type 'linear' as access)"},
|
||||||
|
{Def::kInterpolationType, Use::kAddressSpace,
|
||||||
|
R"(5:6 error: cannot use interpolation type 'linear' as address space)"},
|
||||||
|
{Def::kInterpolationType, Use::kBinaryOp,
|
||||||
|
R"(5:6 error: cannot use interpolation type 'linear' as value)"},
|
||||||
|
{Def::kInterpolationType, Use::kBuiltinValue,
|
||||||
|
R"(5:6 error: cannot use interpolation type 'linear' as builtin value)"},
|
||||||
|
{Def::kInterpolationType, Use::kCallStmt,
|
||||||
|
R"(5:6 error: cannot use interpolation type 'linear' as call target)"},
|
||||||
|
{Def::kInterpolationType, Use::kCallExpr,
|
||||||
|
R"(5:6 error: cannot use interpolation type 'linear' as call target)"},
|
||||||
|
{Def::kInterpolationType, Use::kFunctionReturnType,
|
||||||
|
R"(5:6 error: cannot use interpolation type 'linear' as type)"},
|
||||||
|
{Def::kInterpolationType, Use::kInterpolationSampling,
|
||||||
|
R"(5:6 error: cannot use interpolation type 'linear' as interpolation sampling)"},
|
||||||
|
{Def::kInterpolationType, Use::kInterpolationType, kPass},
|
||||||
|
{Def::kInterpolationType, Use::kMemberType,
|
||||||
|
R"(5:6 error: cannot use interpolation type 'linear' as type)"},
|
||||||
|
{Def::kInterpolationType, Use::kTexelFormat,
|
||||||
|
R"(5:6 error: cannot use interpolation type 'linear' as texel format)"},
|
||||||
|
{Def::kInterpolationType, Use::kValueExpression,
|
||||||
|
R"(5:6 error: cannot use interpolation type 'linear' as value)"},
|
||||||
|
{Def::kInterpolationType, Use::kVariableType,
|
||||||
|
R"(5:6 error: cannot use interpolation type 'linear' as type)"},
|
||||||
|
{Def::kInterpolationType, Use::kUnaryOp,
|
||||||
|
R"(5:6 error: cannot use interpolation type 'linear' as value)"},
|
||||||
|
|
||||||
{Def::kStruct, Use::kAccess, R"(5:6 error: cannot use type 'STRUCT' as access)"},
|
{Def::kStruct, Use::kAccess, R"(5:6 error: cannot use type 'STRUCT' as access)"},
|
||||||
{Def::kStruct, Use::kAddressSpace,
|
{Def::kStruct, Use::kAddressSpace,
|
||||||
R"(5:6 error: cannot use type 'STRUCT' as address space)"},
|
R"(5:6 error: cannot use type 'STRUCT' as address space)"},
|
||||||
@ -433,6 +569,10 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
{Def::kStruct, Use::kBuiltinValue,
|
{Def::kStruct, Use::kBuiltinValue,
|
||||||
R"(5:6 error: cannot use type 'STRUCT' as builtin value)"},
|
R"(5:6 error: cannot use type 'STRUCT' as builtin value)"},
|
||||||
{Def::kStruct, Use::kFunctionReturnType, kPass},
|
{Def::kStruct, Use::kFunctionReturnType, kPass},
|
||||||
|
{Def::kStruct, Use::kInterpolationSampling,
|
||||||
|
R"(5:6 error: cannot use type 'STRUCT' as interpolation sampling)"},
|
||||||
|
{Def::kStruct, Use::kInterpolationType,
|
||||||
|
R"(5:6 error: cannot use type 'STRUCT' as interpolation type)"},
|
||||||
{Def::kStruct, Use::kMemberType, kPass},
|
{Def::kStruct, Use::kMemberType, kPass},
|
||||||
{Def::kStruct, Use::kTexelFormat, R"(5:6 error: cannot use type 'STRUCT' as texel format)"},
|
{Def::kStruct, Use::kTexelFormat, R"(5:6 error: cannot use type 'STRUCT' as texel format)"},
|
||||||
{Def::kStruct, Use::kValueExpression,
|
{Def::kStruct, Use::kValueExpression,
|
||||||
@ -459,6 +599,10 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
R"(5:6 error: cannot use texel format 'rgba8unorm' as call target)"},
|
R"(5:6 error: cannot use texel format 'rgba8unorm' as call target)"},
|
||||||
{Def::kTexelFormat, Use::kFunctionReturnType,
|
{Def::kTexelFormat, Use::kFunctionReturnType,
|
||||||
R"(5:6 error: cannot use texel format 'rgba8unorm' as type)"},
|
R"(5:6 error: cannot use texel format 'rgba8unorm' as type)"},
|
||||||
|
{Def::kTexelFormat, Use::kInterpolationSampling,
|
||||||
|
R"(5:6 error: cannot use texel format 'rgba8unorm' as interpolation sampling)"},
|
||||||
|
{Def::kTexelFormat, Use::kInterpolationType,
|
||||||
|
R"(5:6 error: cannot use texel format 'rgba8unorm' as interpolation type)"},
|
||||||
{Def::kTexelFormat, Use::kMemberType,
|
{Def::kTexelFormat, Use::kMemberType,
|
||||||
R"(5:6 error: cannot use texel format 'rgba8unorm' as type)"},
|
R"(5:6 error: cannot use texel format 'rgba8unorm' as type)"},
|
||||||
{Def::kTexelFormat, Use::kTexelFormat, kPass},
|
{Def::kTexelFormat, Use::kTexelFormat, kPass},
|
||||||
@ -479,6 +623,10 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
R"(5:6 error: cannot use type 'i32' as builtin value)"},
|
R"(5:6 error: cannot use type 'i32' as builtin value)"},
|
||||||
{Def::kTypeAlias, Use::kCallExpr, kPass},
|
{Def::kTypeAlias, Use::kCallExpr, kPass},
|
||||||
{Def::kTypeAlias, Use::kFunctionReturnType, kPass},
|
{Def::kTypeAlias, Use::kFunctionReturnType, kPass},
|
||||||
|
{Def::kTypeAlias, Use::kInterpolationSampling,
|
||||||
|
R"(5:6 error: cannot use type 'i32' as interpolation sampling)"},
|
||||||
|
{Def::kTypeAlias, Use::kInterpolationType,
|
||||||
|
R"(5:6 error: cannot use type 'i32' as interpolation type)"},
|
||||||
{Def::kTypeAlias, Use::kMemberType, kPass},
|
{Def::kTypeAlias, Use::kMemberType, kPass},
|
||||||
{Def::kTypeAlias, Use::kTexelFormat, R"(5:6 error: cannot use type 'i32' as texel format)"},
|
{Def::kTypeAlias, Use::kTexelFormat, R"(5:6 error: cannot use type 'i32' as texel format)"},
|
||||||
{Def::kTypeAlias, Use::kValueExpression,
|
{Def::kTypeAlias, Use::kValueExpression,
|
||||||
@ -506,6 +654,12 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
1:2 note: const 'VARIABLE' declared here)"},
|
1:2 note: const 'VARIABLE' declared here)"},
|
||||||
{Def::kVariable, Use::kFunctionReturnType,
|
{Def::kVariable, Use::kFunctionReturnType,
|
||||||
R"(5:6 error: cannot use const 'VARIABLE' as type
|
R"(5:6 error: cannot use const 'VARIABLE' as type
|
||||||
|
1:2 note: const 'VARIABLE' declared here)"},
|
||||||
|
{Def::kVariable, Use::kInterpolationSampling,
|
||||||
|
R"(5:6 error: cannot use const 'VARIABLE' as interpolation sampling
|
||||||
|
1:2 note: const 'VARIABLE' declared here)"},
|
||||||
|
{Def::kVariable, Use::kInterpolationType,
|
||||||
|
R"(5:6 error: cannot use const 'VARIABLE' as interpolation type
|
||||||
1:2 note: const 'VARIABLE' declared here)"},
|
1:2 note: const 'VARIABLE' declared here)"},
|
||||||
{Def::kVariable, Use::kMemberType,
|
{Def::kVariable, Use::kMemberType,
|
||||||
R"(5:6 error: cannot use const 'VARIABLE' as type
|
R"(5:6 error: cannot use const 'VARIABLE' as type
|
||||||
|
@ -90,6 +90,8 @@
|
|||||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::BuiltinEnumExpression<tint::builtin::Access>);
|
TINT_INSTANTIATE_TYPEINFO(tint::sem::BuiltinEnumExpression<tint::builtin::Access>);
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::BuiltinEnumExpression<tint::builtin::AddressSpace>);
|
TINT_INSTANTIATE_TYPEINFO(tint::sem::BuiltinEnumExpression<tint::builtin::AddressSpace>);
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::BuiltinEnumExpression<tint::builtin::BuiltinValue>);
|
TINT_INSTANTIATE_TYPEINFO(tint::sem::BuiltinEnumExpression<tint::builtin::BuiltinValue>);
|
||||||
|
TINT_INSTANTIATE_TYPEINFO(tint::sem::BuiltinEnumExpression<tint::builtin::InterpolationSampling>);
|
||||||
|
TINT_INSTANTIATE_TYPEINFO(tint::sem::BuiltinEnumExpression<tint::builtin::InterpolationType>);
|
||||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::BuiltinEnumExpression<tint::builtin::TexelFormat>);
|
TINT_INSTANTIATE_TYPEINFO(tint::sem::BuiltinEnumExpression<tint::builtin::TexelFormat>);
|
||||||
|
|
||||||
namespace tint::resolver {
|
namespace tint::resolver {
|
||||||
@ -1521,6 +1523,16 @@ sem::BuiltinEnumExpression<builtin::Access>* Resolver::AccessExpression(
|
|||||||
return sem_.AsAccess(Expression(expr));
|
return sem_.AsAccess(Expression(expr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sem::BuiltinEnumExpression<builtin::InterpolationSampling>* Resolver::InterpolationSampling(
|
||||||
|
const ast::Expression* expr) {
|
||||||
|
return sem_.AsInterpolationSampling(Expression(expr));
|
||||||
|
}
|
||||||
|
|
||||||
|
sem::BuiltinEnumExpression<builtin::InterpolationType>* Resolver::InterpolationType(
|
||||||
|
const ast::Expression* expr) {
|
||||||
|
return sem_.AsInterpolationType(Expression(expr));
|
||||||
|
}
|
||||||
|
|
||||||
void Resolver::RegisterStore(const sem::ValueExpression* expr) {
|
void Resolver::RegisterStore(const sem::ValueExpression* expr) {
|
||||||
auto& info = alias_analysis_infos_[current_function_];
|
auto& info = alias_analysis_infos_[current_function_];
|
||||||
Switch(
|
Switch(
|
||||||
@ -3001,6 +3013,18 @@ sem::Expression* Resolver::Identifier(const ast::IdentifierExpression* expr) {
|
|||||||
expr, current_statement_, builtin);
|
expr, current_statement_, builtin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (auto i_smpl = resolved->InterpolationSampling();
|
||||||
|
i_smpl != builtin::InterpolationSampling::kUndefined) {
|
||||||
|
return builder_->create<sem::BuiltinEnumExpression<builtin::InterpolationSampling>>(
|
||||||
|
expr, current_statement_, i_smpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto i_type = resolved->InterpolationType();
|
||||||
|
i_type != builtin::InterpolationType::kUndefined) {
|
||||||
|
return builder_->create<sem::BuiltinEnumExpression<builtin::InterpolationType>>(
|
||||||
|
expr, current_statement_, i_type);
|
||||||
|
}
|
||||||
|
|
||||||
if (auto fmt = resolved->TexelFormat(); fmt != builtin::TexelFormat::kUndefined) {
|
if (auto fmt = resolved->TexelFormat(); fmt != builtin::TexelFormat::kUndefined) {
|
||||||
return builder_->create<sem::BuiltinEnumExpression<builtin::TexelFormat>>(
|
return builder_->create<sem::BuiltinEnumExpression<builtin::TexelFormat>>(
|
||||||
expr, current_statement_, fmt);
|
expr, current_statement_, fmt);
|
||||||
@ -3326,7 +3350,8 @@ bool Resolver::Attribute(const ast::Attribute* attr) {
|
|||||||
return Switch(
|
return Switch(
|
||||||
attr, //
|
attr, //
|
||||||
[&](const ast::BuiltinAttribute* b) { return BuiltinAttribute(b); },
|
[&](const ast::BuiltinAttribute* b) { return BuiltinAttribute(b); },
|
||||||
[&](const ast::DiagnosticAttribute* dc) { return DiagnosticControl(dc->control); },
|
[&](const ast::DiagnosticAttribute* d) { return DiagnosticControl(d->control); },
|
||||||
|
[&](const ast::InterpolateAttribute* i) { return InterpolateAttribute(i); },
|
||||||
[&](Default) { return true; });
|
[&](Default) { return true; });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3341,6 +3366,16 @@ bool Resolver::BuiltinAttribute(const ast::BuiltinAttribute* attr) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Resolver::InterpolateAttribute(const ast::InterpolateAttribute* attr) {
|
||||||
|
if (!InterpolationType(attr->type)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (attr->sampling && !InterpolationSampling(attr->sampling)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Resolver::DiagnosticControl(const ast::DiagnosticControl& control) {
|
bool Resolver::DiagnosticControl(const ast::DiagnosticControl& control) {
|
||||||
Mark(control.rule_name);
|
Mark(control.rule_name);
|
||||||
|
|
||||||
|
@ -163,6 +163,20 @@ class Resolver {
|
|||||||
/// diagnostic is raised and nullptr is returned.
|
/// diagnostic is raised and nullptr is returned.
|
||||||
sem::BuiltinEnumExpression<builtin::Access>* AccessExpression(const ast::Expression* expr);
|
sem::BuiltinEnumExpression<builtin::Access>* AccessExpression(const ast::Expression* expr);
|
||||||
|
|
||||||
|
/// @returns the call of Expression() cast to a
|
||||||
|
/// sem::BuiltinEnumExpression<builtin::InterpolationSampling>*. If the sem::Expression is not a
|
||||||
|
/// sem::BuiltinEnumExpression<builtin::InterpolationSampling>*, then an error diagnostic is
|
||||||
|
/// raised and nullptr is returned.
|
||||||
|
sem::BuiltinEnumExpression<builtin::InterpolationSampling>* InterpolationSampling(
|
||||||
|
const ast::Expression* expr);
|
||||||
|
|
||||||
|
/// @returns the call of Expression() cast to a
|
||||||
|
/// sem::BuiltinEnumExpression<builtin::InterpolationType>*. If the sem::Expression is not a
|
||||||
|
/// sem::BuiltinEnumExpression<builtin::InterpolationType>*, then an error diagnostic is raised
|
||||||
|
/// and nullptr is returned.
|
||||||
|
sem::BuiltinEnumExpression<builtin::InterpolationType>* InterpolationType(
|
||||||
|
const ast::Expression* expr);
|
||||||
|
|
||||||
/// Expression traverses the graph of expressions starting at `expr`, building a post-ordered
|
/// Expression traverses the graph of expressions starting at `expr`, building a post-ordered
|
||||||
/// list (leaf-first) of all the expression nodes. Each of the expressions are then resolved by
|
/// list (leaf-first) of all the expression nodes. Each of the expressions are then resolved by
|
||||||
/// dispatching to the appropriate expression handlers below.
|
/// dispatching to the appropriate expression handlers below.
|
||||||
@ -304,6 +318,10 @@ class Resolver {
|
|||||||
/// @returns true on success, false on failure
|
/// @returns true on success, false on failure
|
||||||
bool BuiltinAttribute(const ast::BuiltinAttribute* attr);
|
bool BuiltinAttribute(const ast::BuiltinAttribute* attr);
|
||||||
|
|
||||||
|
/// Resolves the `@interpolate` attribute @p attr
|
||||||
|
/// @returns true on success, false on failure
|
||||||
|
bool InterpolateAttribute(const ast::InterpolateAttribute* attr);
|
||||||
|
|
||||||
/// @param control the diagnostic control
|
/// @param control the diagnostic control
|
||||||
/// @returns true on success, false on failure
|
/// @returns true on success, false on failure
|
||||||
bool DiagnosticControl(const ast::DiagnosticControl& control);
|
bool DiagnosticControl(const ast::DiagnosticControl& control);
|
||||||
|
@ -89,6 +89,16 @@ void SemHelper::ErrorUnexpectedExprKind(const sem::Expression* expr,
|
|||||||
std::string(wanted),
|
std::string(wanted),
|
||||||
builtin->Declaration()->source);
|
builtin->Declaration()->source);
|
||||||
},
|
},
|
||||||
|
[&](const sem::BuiltinEnumExpression<builtin::InterpolationSampling>* fmt) {
|
||||||
|
AddError("cannot use interpolation sampling '" + utils::ToString(fmt->Value()) +
|
||||||
|
"' as " + std::string(wanted),
|
||||||
|
fmt->Declaration()->source);
|
||||||
|
},
|
||||||
|
[&](const sem::BuiltinEnumExpression<builtin::InterpolationType>* fmt) {
|
||||||
|
AddError("cannot use interpolation type '" + utils::ToString(fmt->Value()) + "' as " +
|
||||||
|
std::string(wanted),
|
||||||
|
fmt->Declaration()->source);
|
||||||
|
},
|
||||||
[&](const sem::BuiltinEnumExpression<builtin::TexelFormat>* fmt) {
|
[&](const sem::BuiltinEnumExpression<builtin::TexelFormat>* fmt) {
|
||||||
AddError("cannot use texel format '" + utils::ToString(fmt->Value()) + "' as " +
|
AddError("cannot use texel format '" + utils::ToString(fmt->Value()) + "' as " +
|
||||||
std::string(wanted),
|
std::string(wanted),
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "src/tint/builtin/builtin_value.h"
|
#include "src/tint/builtin/builtin_value.h"
|
||||||
|
#include "src/tint/builtin/interpolation_sampling.h"
|
||||||
|
#include "src/tint/builtin/interpolation_type.h"
|
||||||
#include "src/tint/diagnostic/diagnostic.h"
|
#include "src/tint/diagnostic/diagnostic.h"
|
||||||
#include "src/tint/program_builder.h"
|
#include "src/tint/program_builder.h"
|
||||||
#include "src/tint/resolver/dependency_graph.h"
|
#include "src/tint/resolver/dependency_graph.h"
|
||||||
@ -164,6 +166,39 @@ class SemHelper {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @param expr the semantic node
|
||||||
|
/// @returns nullptr if @p expr is nullptr, or @p expr cast to
|
||||||
|
/// sem::BuiltinEnumExpression<builtin::InterpolationSampling> if the cast is successful,
|
||||||
|
/// otherwise an error diagnostic is raised.
|
||||||
|
sem::BuiltinEnumExpression<builtin::InterpolationSampling>* AsInterpolationSampling(
|
||||||
|
sem::Expression* expr) const {
|
||||||
|
if (TINT_LIKELY(expr)) {
|
||||||
|
auto* enum_expr =
|
||||||
|
expr->As<sem::BuiltinEnumExpression<builtin::InterpolationSampling>>();
|
||||||
|
if (TINT_LIKELY(enum_expr)) {
|
||||||
|
return enum_expr;
|
||||||
|
}
|
||||||
|
ErrorUnexpectedExprKind(expr, "interpolation sampling");
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @param expr the semantic node
|
||||||
|
/// @returns nullptr if @p expr is nullptr, or @p expr cast to
|
||||||
|
/// sem::BuiltinEnumExpression<builtin::InterpolationType> if the cast is successful, otherwise
|
||||||
|
/// an error diagnostic is raised.
|
||||||
|
sem::BuiltinEnumExpression<builtin::InterpolationType>* AsInterpolationType(
|
||||||
|
sem::Expression* expr) const {
|
||||||
|
if (TINT_LIKELY(expr)) {
|
||||||
|
auto* enum_expr = expr->As<sem::BuiltinEnumExpression<builtin::InterpolationType>>();
|
||||||
|
if (TINT_LIKELY(enum_expr)) {
|
||||||
|
return enum_expr;
|
||||||
|
}
|
||||||
|
ErrorUnexpectedExprKind(expr, "interpolation type");
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/// @returns the resolved type of the ast::Expression @p expr
|
/// @returns the resolved type of the ast::Expression @p expr
|
||||||
/// @param expr the expression
|
/// @param expr the expression
|
||||||
type::Type* TypeOf(const ast::Expression* expr) const;
|
type::Type* TypeOf(const ast::Expression* expr) const;
|
||||||
|
@ -985,14 +985,19 @@ bool Validator::InterpolateAttribute(const ast::InterpolateAttribute* attr,
|
|||||||
const type::Type* storage_ty) const {
|
const type::Type* storage_ty) const {
|
||||||
auto* type = storage_ty->UnwrapRef();
|
auto* type = storage_ty->UnwrapRef();
|
||||||
|
|
||||||
if (type->is_integer_scalar_or_vector() && attr->type != builtin::InterpolationType::kFlat) {
|
auto i_type = sem_.AsInterpolationType(sem_.Get(attr->type));
|
||||||
|
if (TINT_UNLIKELY(!i_type)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type->is_integer_scalar_or_vector() &&
|
||||||
|
i_type->Value() != builtin::InterpolationType::kFlat) {
|
||||||
AddError("interpolation type must be 'flat' for integral user-defined IO types",
|
AddError("interpolation type must be 'flat' for integral user-defined IO types",
|
||||||
attr->source);
|
attr->source);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr->type == builtin::InterpolationType::kFlat &&
|
if (attr->sampling && i_type->Value() == builtin::InterpolationType::kFlat) {
|
||||||
attr->sampling != builtin::InterpolationSampling::kUndefined) {
|
|
||||||
AddError("flat interpolation attribute must not have a sampling parameter", attr->source);
|
AddError("flat interpolation attribute must not have a sampling parameter", attr->source);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,7 @@ const char* str(BuiltinType i);
|
|||||||
/// matches the name in the WGSL spec.
|
/// matches the name in the WGSL spec.
|
||||||
std::ostream& operator<<(std::ostream& out, BuiltinType i);
|
std::ostream& operator<<(std::ostream& out, BuiltinType i);
|
||||||
|
|
||||||
/// All builtin types
|
/// All builtin function
|
||||||
constexpr BuiltinType kBuiltinTypes[] = {
|
constexpr BuiltinType kBuiltinTypes[] = {
|
||||||
BuiltinType::kAbs,
|
BuiltinType::kAbs,
|
||||||
BuiltinType::kAcos,
|
BuiltinType::kAcos,
|
||||||
@ -279,6 +279,124 @@ constexpr BuiltinType kBuiltinTypes[] = {
|
|||||||
BuiltinType::kTintMaterialize,
|
BuiltinType::kTintMaterialize,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// All builtin function names
|
||||||
|
constexpr const char* kBuiltinStrings[] = {
|
||||||
|
"abs",
|
||||||
|
"acos",
|
||||||
|
"acosh",
|
||||||
|
"all",
|
||||||
|
"any",
|
||||||
|
"arrayLength",
|
||||||
|
"asin",
|
||||||
|
"asinh",
|
||||||
|
"atan",
|
||||||
|
"atan2",
|
||||||
|
"atanh",
|
||||||
|
"ceil",
|
||||||
|
"clamp",
|
||||||
|
"cos",
|
||||||
|
"cosh",
|
||||||
|
"countLeadingZeros",
|
||||||
|
"countOneBits",
|
||||||
|
"countTrailingZeros",
|
||||||
|
"cross",
|
||||||
|
"degrees",
|
||||||
|
"determinant",
|
||||||
|
"distance",
|
||||||
|
"dot",
|
||||||
|
"dot4I8Packed",
|
||||||
|
"dot4U8Packed",
|
||||||
|
"dpdx",
|
||||||
|
"dpdxCoarse",
|
||||||
|
"dpdxFine",
|
||||||
|
"dpdy",
|
||||||
|
"dpdyCoarse",
|
||||||
|
"dpdyFine",
|
||||||
|
"exp",
|
||||||
|
"exp2",
|
||||||
|
"extractBits",
|
||||||
|
"faceForward",
|
||||||
|
"firstLeadingBit",
|
||||||
|
"firstTrailingBit",
|
||||||
|
"floor",
|
||||||
|
"fma",
|
||||||
|
"fract",
|
||||||
|
"frexp",
|
||||||
|
"fwidth",
|
||||||
|
"fwidthCoarse",
|
||||||
|
"fwidthFine",
|
||||||
|
"insertBits",
|
||||||
|
"inverseSqrt",
|
||||||
|
"ldexp",
|
||||||
|
"length",
|
||||||
|
"log",
|
||||||
|
"log2",
|
||||||
|
"max",
|
||||||
|
"min",
|
||||||
|
"mix",
|
||||||
|
"modf",
|
||||||
|
"normalize",
|
||||||
|
"pack2x16float",
|
||||||
|
"pack2x16snorm",
|
||||||
|
"pack2x16unorm",
|
||||||
|
"pack4x8snorm",
|
||||||
|
"pack4x8unorm",
|
||||||
|
"pow",
|
||||||
|
"quantizeToF16",
|
||||||
|
"radians",
|
||||||
|
"reflect",
|
||||||
|
"refract",
|
||||||
|
"reverseBits",
|
||||||
|
"round",
|
||||||
|
"saturate",
|
||||||
|
"select",
|
||||||
|
"sign",
|
||||||
|
"sin",
|
||||||
|
"sinh",
|
||||||
|
"smoothstep",
|
||||||
|
"sqrt",
|
||||||
|
"step",
|
||||||
|
"storageBarrier",
|
||||||
|
"tan",
|
||||||
|
"tanh",
|
||||||
|
"transpose",
|
||||||
|
"trunc",
|
||||||
|
"unpack2x16float",
|
||||||
|
"unpack2x16snorm",
|
||||||
|
"unpack2x16unorm",
|
||||||
|
"unpack4x8snorm",
|
||||||
|
"unpack4x8unorm",
|
||||||
|
"workgroupBarrier",
|
||||||
|
"workgroupUniformLoad",
|
||||||
|
"textureDimensions",
|
||||||
|
"textureGather",
|
||||||
|
"textureGatherCompare",
|
||||||
|
"textureNumLayers",
|
||||||
|
"textureNumLevels",
|
||||||
|
"textureNumSamples",
|
||||||
|
"textureSample",
|
||||||
|
"textureSampleBias",
|
||||||
|
"textureSampleCompare",
|
||||||
|
"textureSampleCompareLevel",
|
||||||
|
"textureSampleGrad",
|
||||||
|
"textureSampleLevel",
|
||||||
|
"textureSampleBaseClampToEdge",
|
||||||
|
"textureStore",
|
||||||
|
"textureLoad",
|
||||||
|
"atomicLoad",
|
||||||
|
"atomicStore",
|
||||||
|
"atomicAdd",
|
||||||
|
"atomicSub",
|
||||||
|
"atomicMax",
|
||||||
|
"atomicMin",
|
||||||
|
"atomicAnd",
|
||||||
|
"atomicOr",
|
||||||
|
"atomicXor",
|
||||||
|
"atomicExchange",
|
||||||
|
"atomicCompareExchangeWeak",
|
||||||
|
"_tint_materialize",
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
||||||
#endif // SRC_TINT_SEM_BUILTIN_TYPE_H_
|
#endif // SRC_TINT_SEM_BUILTIN_TYPE_H_
|
||||||
|
@ -41,13 +41,20 @@ const char* str(BuiltinType i);
|
|||||||
/// matches the name in the WGSL spec.
|
/// matches the name in the WGSL spec.
|
||||||
std::ostream& operator<<(std::ostream& out, BuiltinType i);
|
std::ostream& operator<<(std::ostream& out, BuiltinType i);
|
||||||
|
|
||||||
/// All builtin types
|
/// All builtin function
|
||||||
constexpr BuiltinType kBuiltinTypes[] = {
|
constexpr BuiltinType kBuiltinTypes[] = {
|
||||||
{{- range Sem.Builtins }}
|
{{- range Sem.Builtins }}
|
||||||
BuiltinType::k{{PascalCase .Name}},
|
BuiltinType::k{{PascalCase .Name}},
|
||||||
{{- end }}
|
{{- end }}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// All builtin function names
|
||||||
|
constexpr const char* kBuiltinStrings[] = {
|
||||||
|
{{- range Sem.Builtins }}
|
||||||
|
"{{.Name}}",
|
||||||
|
{{- end }}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
||||||
#endif // SRC_TINT_SEM_BUILTIN_TYPE_H_
|
#endif // SRC_TINT_SEM_BUILTIN_TYPE_H_
|
||||||
|
@ -2191,7 +2191,11 @@ void GeneratorImpl::EmitInterpolationQualifiers(
|
|||||||
utils::VectorRef<const ast::Attribute*> attributes) {
|
utils::VectorRef<const ast::Attribute*> attributes) {
|
||||||
for (auto* attr : attributes) {
|
for (auto* attr : attributes) {
|
||||||
if (auto* interpolate = attr->As<ast::InterpolateAttribute>()) {
|
if (auto* interpolate = attr->As<ast::InterpolateAttribute>()) {
|
||||||
switch (interpolate->type) {
|
auto& sem = program_->Sem();
|
||||||
|
auto i_type =
|
||||||
|
sem.Get<sem::BuiltinEnumExpression<builtin::InterpolationType>>(interpolate->type)
|
||||||
|
->Value();
|
||||||
|
switch (i_type) {
|
||||||
case builtin::InterpolationType::kPerspective:
|
case builtin::InterpolationType::kPerspective:
|
||||||
case builtin::InterpolationType::kLinear:
|
case builtin::InterpolationType::kLinear:
|
||||||
case builtin::InterpolationType::kUndefined:
|
case builtin::InterpolationType::kUndefined:
|
||||||
@ -2200,14 +2204,20 @@ void GeneratorImpl::EmitInterpolationQualifiers(
|
|||||||
out << "flat ";
|
out << "flat ";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (interpolate->sampling) {
|
|
||||||
case builtin::InterpolationSampling::kCentroid:
|
if (interpolate->sampling) {
|
||||||
out << "centroid ";
|
auto i_smpl = sem.Get<sem::BuiltinEnumExpression<builtin::InterpolationSampling>>(
|
||||||
break;
|
interpolate->sampling)
|
||||||
case builtin::InterpolationSampling::kSample:
|
->Value();
|
||||||
case builtin::InterpolationSampling::kCenter:
|
switch (i_smpl) {
|
||||||
case builtin::InterpolationSampling::kUndefined:
|
case builtin::InterpolationSampling::kCentroid:
|
||||||
break;
|
out << "centroid ";
|
||||||
|
break;
|
||||||
|
case builtin::InterpolationSampling::kSample:
|
||||||
|
case builtin::InterpolationSampling::kCenter:
|
||||||
|
case builtin::InterpolationSampling::kUndefined:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4219,8 +4219,21 @@ bool GeneratorImpl::EmitStructType(TextBuffer* b, const sem::Struct* str) {
|
|||||||
}
|
}
|
||||||
post += " : " + name;
|
post += " : " + name;
|
||||||
} else if (auto* interpolate = attr->As<ast::InterpolateAttribute>()) {
|
} else if (auto* interpolate = attr->As<ast::InterpolateAttribute>()) {
|
||||||
auto mod =
|
auto& sem = program_->Sem();
|
||||||
interpolation_to_modifiers(interpolate->type, interpolate->sampling);
|
auto i_type =
|
||||||
|
sem.Get<sem::BuiltinEnumExpression<builtin::InterpolationType>>(
|
||||||
|
interpolate->type)
|
||||||
|
->Value();
|
||||||
|
|
||||||
|
auto i_smpl = builtin::InterpolationSampling::kUndefined;
|
||||||
|
if (interpolate->sampling) {
|
||||||
|
i_smpl =
|
||||||
|
sem.Get<sem::BuiltinEnumExpression<builtin::InterpolationSampling>>(
|
||||||
|
interpolate->sampling)
|
||||||
|
->Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto mod = interpolation_to_modifiers(i_type, i_smpl);
|
||||||
if (mod.empty()) {
|
if (mod.empty()) {
|
||||||
diagnostics_.add_error(diag::System::Writer,
|
diagnostics_.add_error(diag::System::Writer,
|
||||||
"unsupported interpolation");
|
"unsupported interpolation");
|
||||||
|
@ -2891,8 +2891,21 @@ bool GeneratorImpl::EmitStructType(TextBuffer* b, const sem::Struct* str) {
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[&](const ast::InterpolateAttribute* interpolate) {
|
[&](const ast::InterpolateAttribute* interpolate) {
|
||||||
auto name =
|
auto& sem = program_->Sem();
|
||||||
interpolation_to_attribute(interpolate->type, interpolate->sampling);
|
auto i_type =
|
||||||
|
sem.Get<sem::BuiltinEnumExpression<builtin::InterpolationType>>(
|
||||||
|
interpolate->type)
|
||||||
|
->Value();
|
||||||
|
|
||||||
|
auto i_smpl = builtin::InterpolationSampling::kUndefined;
|
||||||
|
if (interpolate->sampling) {
|
||||||
|
i_smpl =
|
||||||
|
sem.Get<sem::BuiltinEnumExpression<builtin::InterpolationSampling>>(
|
||||||
|
interpolate->sampling)
|
||||||
|
->Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto name = interpolation_to_attribute(i_type, i_smpl);
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
diagnostics_.add_error(diag::System::Writer,
|
diagnostics_.add_error(diag::System::Writer,
|
||||||
"unknown interpolation attribute");
|
"unknown interpolation attribute");
|
||||||
|
@ -851,7 +851,19 @@ bool Builder::GenerateGlobalVariable(const ast::Variable* v) {
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[&](const ast::InterpolateAttribute* interpolate) {
|
[&](const ast::InterpolateAttribute* interpolate) {
|
||||||
AddInterpolationDecorations(var_id, interpolate->type, interpolate->sampling);
|
auto& s = builder_.Sem();
|
||||||
|
auto i_type =
|
||||||
|
s.Get<sem::BuiltinEnumExpression<builtin::InterpolationType>>(interpolate->type)
|
||||||
|
->Value();
|
||||||
|
|
||||||
|
auto i_smpl = builtin::InterpolationSampling::kUndefined;
|
||||||
|
if (interpolate->sampling) {
|
||||||
|
i_smpl = s.Get<sem::BuiltinEnumExpression<builtin::InterpolationSampling>>(
|
||||||
|
interpolate->sampling)
|
||||||
|
->Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
AddInterpolationDecorations(var_id, i_type, i_smpl);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[&](const ast::InvariantAttribute*) {
|
[&](const ast::InvariantAttribute*) {
|
||||||
|
@ -575,9 +575,15 @@ bool GeneratorImpl::EmitAttributes(std::ostream& out,
|
|||||||
return EmitDiagnosticControl(out, diagnostic->control);
|
return EmitDiagnosticControl(out, diagnostic->control);
|
||||||
},
|
},
|
||||||
[&](const ast::InterpolateAttribute* interpolate) {
|
[&](const ast::InterpolateAttribute* interpolate) {
|
||||||
out << "interpolate(" << interpolate->type;
|
out << "interpolate(";
|
||||||
if (interpolate->sampling != builtin::InterpolationSampling::kUndefined) {
|
if (!EmitExpression(out, interpolate->type)) {
|
||||||
out << ", " << interpolate->sampling;
|
return false;
|
||||||
|
}
|
||||||
|
if (interpolate->sampling) {
|
||||||
|
out << ", ";
|
||||||
|
if (!EmitExpression(out, interpolate->sampling)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
out << ")";
|
out << ")";
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user