Implement textureSample builtins

Handle wsgl parsing and spirv writing of:
  textureSample(), textureSampleBias(), textureSampleLevel(),
  textureSampleGrad(), textureSampleCompare()

Handle the different signature for array texture types.
Includes offset overloads.

Change-Id: I6802d97cd9a7083f12439b32725b9a4b666b8c63
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/32985
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: David Neto <dneto@google.com>
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
Ben Clayton
2020-11-18 21:19:22 +00:00
committed by Commit Bot service account
parent 2f4096b0d7
commit 3ea3c997b5
13 changed files with 3745 additions and 674 deletions

View File

@@ -15,7 +15,9 @@
#ifndef SRC_AST_IDENTIFIER_EXPRESSION_H_
#define SRC_AST_IDENTIFIER_EXPRESSION_H_
#include <memory>
#include <string>
#include <utility>
#include "src/ast/expression.h"
#include "src/ast/intrinsic.h"
@@ -45,6 +47,17 @@ class IdentifierExpression : public Expression {
void set_intrinsic(Intrinsic i) { intrinsic_ = i; }
/// @returns the intrinsic this identifier represents
Intrinsic intrinsic() const { return intrinsic_; }
/// Sets the intrinsic signature
/// @param s the intrinsic signature to set
void set_intrinsic_signature(std::unique_ptr<intrinsic::Signature> s) {
intrinsic_sig_ = std::move(s);
}
/// @returns the intrinsic signature for this identifier.
const intrinsic::Signature* intrinsic_signature() const {
return intrinsic_sig_.get();
}
/// @returns true if this identifier is for an intrinsic
bool IsIntrinsic() const { return intrinsic_ != Intrinsic::kNone; }
@@ -63,6 +76,7 @@ class IdentifierExpression : public Expression {
IdentifierExpression(const IdentifierExpression&) = delete;
Intrinsic intrinsic_ = Intrinsic::kNone;
std::unique_ptr<intrinsic::Signature> intrinsic_sig_;
std::string name_;
};

View File

@@ -216,6 +216,9 @@ std::ostream& operator<<(std::ostream& out, Intrinsic i) {
case Intrinsic::kTextureSampleCompare:
out << "textureSampleCompare";
break;
case Intrinsic::kTextureSampleGrad:
out << "textureSampleGrad";
break;
case Intrinsic::kTextureSampleLevel:
out << "textureSampleLevel";
break;
@@ -231,6 +234,12 @@ std::ostream& operator<<(std::ostream& out, Intrinsic i) {
namespace intrinsic {
Signature::~Signature() = default;
TextureSignature::~TextureSignature() = default;
TextureSignature::Parameters::Index::Index() = default;
TextureSignature::Parameters::Index::Index(const Index&) = default;
bool IsCoarseDerivative(ast::Intrinsic i) {
return i == Intrinsic::kDpdxCoarse || i == Intrinsic::kDpdyCoarse ||
i == Intrinsic::kFwidthCoarse;
@@ -256,7 +265,8 @@ bool IsTextureIntrinsic(ast::Intrinsic i) {
return i == Intrinsic::kTextureLoad || i == Intrinsic::kTextureSample ||
i == Intrinsic::kTextureSampleLevel ||
i == Intrinsic::kTextureSampleBias ||
i == Intrinsic::kTextureSampleCompare;
i == Intrinsic::kTextureSampleCompare ||
i == Intrinsic::kTextureSampleGrad;
}
} // namespace intrinsic

View File

@@ -89,6 +89,7 @@ enum class Intrinsic {
kTextureSample,
kTextureSampleBias,
kTextureSampleCompare,
kTextureSampleGrad,
kTextureSampleLevel,
kTrunc
};
@@ -99,6 +100,64 @@ std::ostream& operator<<(std::ostream& out, Intrinsic i);
namespace intrinsic {
/// Signature is the base struct for all intrinsic signature types.
/// Signatures are used to identify the particular overload for intrinsics that
/// have different signatures with the same function name.
struct Signature {
virtual ~Signature();
};
/// TextureSignature describes the signature of a texture intrinsic function.
struct TextureSignature : public Signature {
/// Parameters describes the parameters for the texture function.
struct Parameters {
/// kNotUsed is the constant that indicates the given parameter is not part
/// of the texture function signature.
static constexpr const size_t kNotUsed = ~static_cast<size_t>(0u);
/// Index holds each of the possible parameter indices. If a parameter index
/// is equal to `kNotUsed` then this parameter is not used by the function.
struct Index {
/// Constructor
Index();
/// Copy constructor
Index(const Index&);
/// `array_index` parameter index.
size_t array_index = kNotUsed;
/// `bias` parameter index.
size_t bias = kNotUsed;
/// `coords` parameter index.
size_t coords = kNotUsed;
/// `depth_ref` parameter index.
size_t depth_ref = kNotUsed;
/// `ddx` parameter index.
size_t ddx = kNotUsed;
/// `ddy` parameter index.
size_t ddy = kNotUsed;
/// `level` parameter index.
size_t level = kNotUsed;
/// `offset` parameter index.
size_t offset = kNotUsed;
/// `sampler` parameter index.
size_t sampler = kNotUsed;
/// `texture` parameter index.
size_t texture = kNotUsed;
};
/// The indices of all possible parameters.
Index idx;
/// Total number of parameters.
size_t count = 0;
};
/// Construct an immutable `TextureSignature`.
/// @param p the texture intrinsic parameter signature.
explicit TextureSignature(const Parameters& p) : params(p) {}
~TextureSignature() override;
/// The texture intrinsic parameter signature.
const Parameters params;
};
/// Determines if the given |name| is a coarse derivative
/// @param i the intrinsic
/// @returns true if the given derivative is coarse.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,171 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_INTRINSIC_TEXTURE_HELPER_TEST_H_
#define SRC_AST_INTRINSIC_TEXTURE_HELPER_TEST_H_
#include <functional>
#include <vector>
#include "src/ast/builder.h"
#include "src/ast/type/sampler_type.h"
#include "src/ast/type/texture_type.h"
namespace tint {
namespace ast {
namespace intrinsic {
namespace test {
enum class TextureKind { kRegular, kDepth };
inline std::ostream& operator<<(std::ostream& out, const TextureKind& kind) {
switch (kind) {
case TextureKind::kRegular:
out << "regular";
break;
case TextureKind::kDepth:
out << "depth";
break;
}
return out;
}
enum class TextureDataType { kF32, kU32, kI32 };
inline std::ostream& operator<<(std::ostream& out, const TextureDataType& ty) {
switch (ty) {
case TextureDataType::kF32:
out << "f32";
break;
case TextureDataType::kU32:
out << "u32";
break;
case TextureDataType::kI32:
out << "i32";
break;
}
return out;
}
enum class ValidTextureOverload {
kSample1dF32,
kSample1dArrayF32,
kSample2dF32,
kSample2dOffsetF32,
kSample2dArrayF32,
kSample2dArrayOffsetF32,
kSample3dF32,
kSample3dOffsetF32,
kSampleCubeF32,
kSampleCubeArrayF32,
kSampleDepth2dF32,
kSampleDepth2dOffsetF32,
kSampleDepth2dArrayF32,
kSampleDepth2dArrayOffsetF32,
kSampleDepthCubeF32,
kSampleDepthCubeArrayF32,
kSampleBias2dF32,
kSampleBias2dOffsetF32,
kSampleBias2dArrayF32,
kSampleBias2dArrayOffsetF32,
kSampleBias3dF32,
kSampleBias3dOffsetF32,
kSampleBiasCubeF32,
kSampleBiasCubeArrayF32,
kSampleLevel2dF32,
kSampleLevel2dOffsetF32,
kSampleLevel2dArrayF32,
kSampleLevel2dArrayOffsetF32,
kSampleLevel3dF32,
kSampleLevel3dOffsetF32,
kSampleLevelCubeF32,
kSampleLevelCubeArrayF32,
kSampleLevelDepth2dF32,
kSampleLevelDepth2dOffsetF32,
kSampleLevelDepth2dArrayF32,
kSampleLevelDepth2dArrayOffsetF32,
kSampleLevelDepthCubeF32,
kSampleLevelDepthCubeArrayF32,
kSampleGrad2dF32,
kSampleGrad2dOffsetF32,
kSampleGrad2dArrayF32,
kSampleGrad2dArrayOffsetF32,
kSampleGrad3dF32,
kSampleGrad3dOffsetF32,
kSampleGradCubeF32,
kSampleGradCubeArrayF32,
kSampleGradDepth2dF32,
kSampleGradDepth2dOffsetF32,
kSampleGradDepth2dArrayF32,
kSampleGradDepth2dArrayOffsetF32,
kSampleGradDepthCubeF32,
kSampleGradDepthCubeArrayF32,
};
/// Describes a texture intrinsic overload
struct TextureOverloadCase {
/// Constructor
TextureOverloadCase();
/// Constructor
TextureOverloadCase(ValidTextureOverload,
const char*,
TextureKind,
ast::type::SamplerKind,
ast::type::TextureDimension,
TextureDataType,
const char*,
std::function<ast::ExpressionList(ast::Builder*)>);
/// Copy constructor
TextureOverloadCase(const TextureOverloadCase&);
/// Destructor
~TextureOverloadCase();
/// @return a vector containing a large number of valid texture overloads
static std::vector<TextureOverloadCase> ValidCases();
/// The enumerator for this overload
ValidTextureOverload overload;
/// A human readable description of the overload
const char* description;
/// The texture kind for the texture parameter
TextureKind texture_kind;
/// The sampler kind for the sampler parameter
ast::type::SamplerKind sampler_kind;
/// The dimensions of the texture parameter
ast::type::TextureDimension texture_dimension;
/// The data type of the texture parameter
TextureDataType texture_data_type;
/// Name of the function. e.g. `textureSample`, `textureSampleGrad`, etc
const char* function;
/// A function that builds the AST arguments for the overload
std::function<ast::ExpressionList(ast::Builder*)> args;
};
inline std::ostream& operator<<(std::ostream& out,
const TextureOverloadCase& data) {
out << "TextureOverloadCase" << static_cast<int>(data.overload) << "\n";
out << data.description << "\n";
out << "texture_kind: " << data.texture_kind << "\n";
out << "sampler_kind: " << data.sampler_kind << "\n";
out << "texture_dimension: " << data.texture_dimension << "\n";
out << "texture_data_type: " << data.texture_data_type << "\n";
return out;
}
} // namespace test
} // namespace intrinsic
} // namespace ast
} // namespace tint
#endif // SRC_AST_INTRINSIC_TEXTURE_HELPER_TEST_H_