Implement textureDimensions()
SPIR-V reader TODO. Bug: tint:140 Bug: tint:437 Change-Id: Ia3a6cb0b36142142d3dc8662281e1860c609c82b Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/36980 Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
c3c70f848a
commit
4a0b9f77ef
|
@ -262,13 +262,18 @@ bool IsFloatClassificationIntrinsic(Intrinsic i) {
|
|||
}
|
||||
|
||||
bool IsTextureIntrinsic(Intrinsic i) {
|
||||
return i == Intrinsic::kTextureLoad || i == Intrinsic::kTextureSample ||
|
||||
return i == Intrinsic::kTextureDimensions || i == Intrinsic::kTextureLoad ||
|
||||
i == Intrinsic::kTextureSample ||
|
||||
i == Intrinsic::kTextureSampleLevel ||
|
||||
i == Intrinsic::kTextureSampleBias ||
|
||||
i == Intrinsic::kTextureSampleCompare ||
|
||||
i == Intrinsic::kTextureSampleGrad || i == Intrinsic::kTextureStore;
|
||||
}
|
||||
|
||||
bool IsImageQueryIntrinsic(Intrinsic i) {
|
||||
return i == ast::Intrinsic::kTextureDimensions;
|
||||
}
|
||||
|
||||
} // namespace intrinsic
|
||||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
|
|
@ -84,6 +84,7 @@ enum class Intrinsic {
|
|||
kStep,
|
||||
kTan,
|
||||
kTanh,
|
||||
kTextureDimensions,
|
||||
kTextureLoad,
|
||||
kTextureSample,
|
||||
kTextureSampleBias,
|
||||
|
@ -187,6 +188,11 @@ bool IsFloatClassificationIntrinsic(Intrinsic i);
|
|||
/// @returns true if the given `i` is a texture operation intrinsic
|
||||
bool IsTextureIntrinsic(Intrinsic i);
|
||||
|
||||
/// Determines if the given `i` is a image query intrinsic
|
||||
/// @param i the intrinsic
|
||||
/// @returns true if the given `i` is a image query intrinsic
|
||||
bool IsImageQueryIntrinsic(Intrinsic i);
|
||||
|
||||
} // namespace intrinsic
|
||||
} // namespace ast
|
||||
} // namespace tint
|
||||
|
|
|
@ -186,6 +186,344 @@ ast::Variable* TextureOverloadCase::buildSamplerVariable(
|
|||
|
||||
std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
|
||||
return {
|
||||
{
|
||||
ValidTextureOverload::kDimensions1d,
|
||||
"textureDimensions(t : texture_1d<f32>) -> i32",
|
||||
TextureKind::kRegular,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::k1d,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensions1dArray,
|
||||
"textureDimensions(t : texture_1d_array<f32>) -> i32",
|
||||
TextureKind::kRegular,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::k1dArray,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensions2d,
|
||||
"textureDimensions(t : texture_2d<f32>) -> vec2<i32>",
|
||||
TextureKind::kRegular,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::k2d,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensions2dLevel,
|
||||
"textureDimensions(t : texture_2d<f32>,\n"
|
||||
" level : i32) -> vec2<i32>",
|
||||
TextureKind::kRegular,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::k2d,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture", 1); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensions2dArray,
|
||||
"textureDimensions(t : texture_2d_array<f32>) -> vec2<i32>",
|
||||
TextureKind::kRegular,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::k2dArray,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensions2dArrayLevel,
|
||||
"textureDimensions(t : texture_2d_array<f32>,\n"
|
||||
" level : i32) -> vec2<i32>",
|
||||
TextureKind::kRegular,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::k2dArray,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture", 1); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensions3d,
|
||||
"textureDimensions(t : texture_3d<f32>) -> vec3<i32>",
|
||||
TextureKind::kRegular,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::k3d,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensions3dLevel,
|
||||
"textureDimensions(t : texture_3d<f32>,\n"
|
||||
" level : i32) -> vec3<i32>",
|
||||
TextureKind::kRegular,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::k3d,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture", 1); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsCube,
|
||||
"textureDimensions(t : texture_cube<f32>) -> vec3<i32>",
|
||||
TextureKind::kRegular,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::kCube,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsCubeLevel,
|
||||
"textureDimensions(t : texture_cube<f32>,\n"
|
||||
" level : i32) -> vec3<i32>",
|
||||
TextureKind::kRegular,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::kCube,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture", 1); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsCubeArray,
|
||||
"textureDimensions(t : texture_cube_array<f32>) -> vec3<i32>",
|
||||
TextureKind::kRegular,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::kCubeArray,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsCubeArrayLevel,
|
||||
"textureDimensions(t : texture_cube_array<f32>,\n"
|
||||
" level : i32) -> vec3<i32>",
|
||||
TextureKind::kRegular,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::kCubeArray,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture", 1); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsMultisampled_2d,
|
||||
"textureDimensions(t : texture_multisampled_2d<f32>)-> vec2<i32>",
|
||||
TextureKind::kMultisampled,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::k2d,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsMultisampled_2dArray,
|
||||
"textureDimensions(t : texture_multisampled_2d_array<f32>)-> "
|
||||
"vec2<i32>",
|
||||
TextureKind::kMultisampled,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::k2dArray,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsDepth2d,
|
||||
"textureDimensions(t : texture_depth_2d) -> vec2<i32>",
|
||||
TextureKind::kDepth,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::k2d,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsDepth2dLevel,
|
||||
"textureDimensions(t : texture_depth_2d,\n"
|
||||
" level : i32) -> vec2<i32>",
|
||||
TextureKind::kDepth,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::k2d,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture", 1); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsDepth2dArray,
|
||||
"textureDimensions(t : texture_depth_2d_array) -> vec2<i32>",
|
||||
TextureKind::kDepth,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::k2dArray,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsDepth2dArrayLevel,
|
||||
"textureDimensions(t : texture_depth_2d_array,\n"
|
||||
" level : i32) -> vec2<i32>",
|
||||
TextureKind::kDepth,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::k2dArray,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture", 1); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsDepthCube,
|
||||
"textureDimensions(t : texture_depth_cube) -> vec3<i32>",
|
||||
TextureKind::kDepth,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::kCube,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsDepthCubeLevel,
|
||||
"textureDimensions(t : texture_depth_cube,\n"
|
||||
" level : i32) -> vec3<i32>",
|
||||
TextureKind::kDepth,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::kCube,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture", 1); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsDepthCubeArray,
|
||||
"textureDimensions(t : texture_depth_cube_array) -> vec3<i32>",
|
||||
TextureKind::kDepth,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::kCubeArray,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsDepthCubeArrayLevel,
|
||||
"textureDimensions(t : texture_depth_cube_array,\n"
|
||||
" level : i32) -> vec3<i32>",
|
||||
TextureKind::kDepth,
|
||||
type::SamplerKind::kSampler,
|
||||
type::TextureDimension::kCubeArray,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture", 1); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsStorageRO1d,
|
||||
"textureDimensions(t : texture_storage_ro_1d<rgba32float>) -> i32",
|
||||
ast::AccessControl::kReadOnly,
|
||||
ast::type::ImageFormat::kRgba32Float,
|
||||
type::TextureDimension::k1d,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsStorageRO1dArray,
|
||||
"textureDimensions(t : texture_storage_ro_1d_array<rgba32float>) -> "
|
||||
"i32",
|
||||
ast::AccessControl::kReadOnly,
|
||||
ast::type::ImageFormat::kRgba32Float,
|
||||
type::TextureDimension::k1dArray,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsStorageRO2d,
|
||||
"textureDimensions(t : texture_storage_ro_2d<rgba32float>) -> "
|
||||
"vec2<i32>",
|
||||
ast::AccessControl::kReadOnly,
|
||||
ast::type::ImageFormat::kRgba32Float,
|
||||
type::TextureDimension::k2d,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsStorageRO2dArray,
|
||||
"textureDimensions(t : texture_storage_ro_2d_array<rgba32float>) -> "
|
||||
"vec2<i32>",
|
||||
ast::AccessControl::kReadOnly,
|
||||
ast::type::ImageFormat::kRgba32Float,
|
||||
type::TextureDimension::k2dArray,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsStorageRO3d,
|
||||
"textureDimensions(t : texture_storage_ro_3d<rgba32float>) -> "
|
||||
"vec3<i32>",
|
||||
ast::AccessControl::kReadOnly,
|
||||
ast::type::ImageFormat::kRgba32Float,
|
||||
type::TextureDimension::k3d,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsStorageWO1d,
|
||||
"textureDimensions(t : texture_storage_wo_1d<rgba32float>) -> i32",
|
||||
ast::AccessControl::kWriteOnly,
|
||||
ast::type::ImageFormat::kRgba32Float,
|
||||
type::TextureDimension::k1d,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsStorageWO1dArray,
|
||||
"textureDimensions(t : texture_storage_wo_1d_array<rgba32float>) -> "
|
||||
"i32",
|
||||
ast::AccessControl::kWriteOnly,
|
||||
ast::type::ImageFormat::kRgba32Float,
|
||||
type::TextureDimension::k1dArray,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsStorageWO2d,
|
||||
"textureDimensions(t : texture_storage_wo_2d<rgba32float>) -> "
|
||||
"vec2<i32>",
|
||||
ast::AccessControl::kWriteOnly,
|
||||
ast::type::ImageFormat::kRgba32Float,
|
||||
type::TextureDimension::k2d,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsStorageWO2dArray,
|
||||
"textureDimensions(t : texture_storage_wo_2d_array<rgba32float>) -> "
|
||||
"vec2<i32>",
|
||||
ast::AccessControl::kWriteOnly,
|
||||
ast::type::ImageFormat::kRgba32Float,
|
||||
type::TextureDimension::k2dArray,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kDimensionsStorageWO3d,
|
||||
"textureDimensions(t : texture_storage_wo_3d<rgba32float>) -> "
|
||||
"vec3<i32>",
|
||||
ast::AccessControl::kWriteOnly,
|
||||
ast::type::ImageFormat::kRgba32Float,
|
||||
type::TextureDimension::k3d,
|
||||
TextureDataType::kF32,
|
||||
"textureDimensions",
|
||||
[](Builder* b) { return b->ExprList("texture"); },
|
||||
},
|
||||
{
|
||||
ValidTextureOverload::kSample1dF32,
|
||||
"textureSample(t : texture_1d<f32>,\n"
|
||||
|
|
|
@ -36,6 +36,38 @@ std::ostream& operator<<(std::ostream& out, const TextureDataType& ty);
|
|||
|
||||
/// Non-exhaustive list of valid texture overloads
|
||||
enum class ValidTextureOverload {
|
||||
kDimensions1d,
|
||||
kDimensions1dArray,
|
||||
kDimensions2d,
|
||||
kDimensions2dLevel,
|
||||
kDimensions2dArray,
|
||||
kDimensions2dArrayLevel,
|
||||
kDimensions3d,
|
||||
kDimensions3dLevel,
|
||||
kDimensionsCube,
|
||||
kDimensionsCubeLevel,
|
||||
kDimensionsCubeArray,
|
||||
kDimensionsCubeArrayLevel,
|
||||
kDimensionsMultisampled_2d,
|
||||
kDimensionsMultisampled_2dArray,
|
||||
kDimensionsDepth2d,
|
||||
kDimensionsDepth2dLevel,
|
||||
kDimensionsDepth2dArray,
|
||||
kDimensionsDepth2dArrayLevel,
|
||||
kDimensionsDepthCube,
|
||||
kDimensionsDepthCubeLevel,
|
||||
kDimensionsDepthCubeArray,
|
||||
kDimensionsDepthCubeArrayLevel,
|
||||
kDimensionsStorageRO1d,
|
||||
kDimensionsStorageRO1dArray,
|
||||
kDimensionsStorageRO2d,
|
||||
kDimensionsStorageRO2dArray,
|
||||
kDimensionsStorageRO3d,
|
||||
kDimensionsStorageWO1d,
|
||||
kDimensionsStorageWO1dArray,
|
||||
kDimensionsStorageWO2d,
|
||||
kDimensionsStorageWO2dArray,
|
||||
kDimensionsStorageWO3d,
|
||||
kSample1dF32,
|
||||
kSample1dArrayF32,
|
||||
kSample2dF32,
|
||||
|
|
|
@ -56,6 +56,22 @@ std::ostream& operator<<(std::ostream& out, TextureDimension dim) {
|
|||
return out;
|
||||
}
|
||||
|
||||
bool IsTextureArray(TextureDimension dim) {
|
||||
switch (dim) {
|
||||
case TextureDimension::k1dArray:
|
||||
case TextureDimension::k2dArray:
|
||||
case TextureDimension::kCubeArray:
|
||||
return true;
|
||||
case TextureDimension::k2d:
|
||||
case TextureDimension::kNone:
|
||||
case TextureDimension::k1d:
|
||||
case TextureDimension::k3d:
|
||||
case TextureDimension::kCube:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Texture::Texture(TextureDimension dim) : dim_(dim) {}
|
||||
|
||||
Texture::Texture(Texture&&) = default;
|
||||
|
|
|
@ -42,6 +42,10 @@ enum class TextureDimension {
|
|||
};
|
||||
std::ostream& operator<<(std::ostream& out, TextureDimension dim);
|
||||
|
||||
/// @param dim the TextureDimension to query
|
||||
/// @return true if the given TextureDimension is an array texture
|
||||
bool IsTextureArray(TextureDimension dim);
|
||||
|
||||
/// A texture type.
|
||||
class Texture : public Castable<Texture, Type> {
|
||||
public:
|
||||
|
|
|
@ -556,18 +556,15 @@ bool TypeDeterminer::DetermineIntrinsic(ast::IdentifierExpression* ident,
|
|||
->UnwrapPtrIfNeeded()
|
||||
->As<ast::type::Texture>();
|
||||
|
||||
bool is_array = false;
|
||||
bool is_array = ast::type::IsTextureArray(texture->dim());
|
||||
bool is_multisampled = texture->Is<ast::type::MultisampledTexture>();
|
||||
switch (texture->dim()) {
|
||||
case ast::type::TextureDimension::k1dArray:
|
||||
case ast::type::TextureDimension::k2dArray:
|
||||
case ast::type::TextureDimension::kCubeArray:
|
||||
is_array = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (ident->intrinsic()) {
|
||||
case ast::Intrinsic::kTextureDimensions:
|
||||
param.idx.texture = param.count++;
|
||||
if (expr->params().size() > param.count) {
|
||||
param.idx.level = param.count++;
|
||||
}
|
||||
break;
|
||||
case ast::Intrinsic::kTextureLoad:
|
||||
param.idx.texture = param.count++;
|
||||
param.idx.coords = param.count++;
|
||||
|
@ -671,7 +668,27 @@ bool TypeDeterminer::DetermineIntrinsic(ast::IdentifierExpression* ident,
|
|||
|
||||
// Set the function return type
|
||||
ast::type::Type* return_type = nullptr;
|
||||
if (ident->intrinsic() == ast::Intrinsic::kTextureStore) {
|
||||
if (ident->intrinsic() == ast::Intrinsic::kTextureDimensions) {
|
||||
auto* i32 = mod_->create<ast::type::I32>();
|
||||
switch (texture->dim()) {
|
||||
default:
|
||||
set_error(expr->source(), "invalid texture dimensions");
|
||||
break;
|
||||
case ast::type::TextureDimension::k1d:
|
||||
case ast::type::TextureDimension::k1dArray:
|
||||
return_type = i32;
|
||||
break;
|
||||
case ast::type::TextureDimension::k2d:
|
||||
case ast::type::TextureDimension::k2dArray:
|
||||
return_type = mod_->create<ast::type::Vector>(i32, 2);
|
||||
break;
|
||||
case ast::type::TextureDimension::k3d:
|
||||
case ast::type::TextureDimension::kCube:
|
||||
case ast::type::TextureDimension::kCubeArray:
|
||||
return_type = mod_->create<ast::type::Vector>(i32, 3);
|
||||
break;
|
||||
}
|
||||
} else if (ident->intrinsic() == ast::Intrinsic::kTextureStore) {
|
||||
return_type = mod_->create<ast::type::Void>();
|
||||
} else {
|
||||
if (texture->Is<ast::type::DepthTexture>()) {
|
||||
|
@ -1025,6 +1042,8 @@ bool TypeDeterminer::SetIntrinsicIfNeeded(ast::IdentifierExpression* ident) {
|
|||
ident->set_intrinsic(ast::Intrinsic::kTan);
|
||||
} else if (name == "tanh") {
|
||||
ident->set_intrinsic(ast::Intrinsic::kTanh);
|
||||
} else if (name == "textureDimensions") {
|
||||
ident->set_intrinsic(ast::Intrinsic::kTextureDimensions);
|
||||
} else if (name == "textureLoad") {
|
||||
ident->set_intrinsic(ast::Intrinsic::kTextureLoad);
|
||||
} else if (name == "textureStore") {
|
||||
|
|
|
@ -1812,6 +1812,7 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
IntrinsicData{"step", ast::Intrinsic::kStep},
|
||||
IntrinsicData{"tan", ast::Intrinsic::kTan},
|
||||
IntrinsicData{"tanh", ast::Intrinsic::kTanh},
|
||||
IntrinsicData{"textureDimensions", ast::Intrinsic::kTextureDimensions},
|
||||
IntrinsicData{"textureLoad", ast::Intrinsic::kTextureLoad},
|
||||
IntrinsicData{"textureSample", ast::Intrinsic::kTextureSample},
|
||||
IntrinsicData{"textureSampleBias", ast::Intrinsic::kTextureSampleBias},
|
||||
|
@ -2953,6 +2954,40 @@ const char* expected_texture_overload(
|
|||
ast::intrinsic::test::ValidTextureOverload overload) {
|
||||
using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
|
||||
switch (overload) {
|
||||
case ValidTextureOverload::kDimensions1d:
|
||||
case ValidTextureOverload::kDimensions1dArray:
|
||||
case ValidTextureOverload::kDimensions2d:
|
||||
case ValidTextureOverload::kDimensions2dArray:
|
||||
case ValidTextureOverload::kDimensions3d:
|
||||
case ValidTextureOverload::kDimensionsCube:
|
||||
case ValidTextureOverload::kDimensionsCubeArray:
|
||||
case ValidTextureOverload::kDimensionsMultisampled_2d:
|
||||
case ValidTextureOverload::kDimensionsMultisampled_2dArray:
|
||||
case ValidTextureOverload::kDimensionsDepth2d:
|
||||
case ValidTextureOverload::kDimensionsDepth2dArray:
|
||||
case ValidTextureOverload::kDimensionsDepthCube:
|
||||
case ValidTextureOverload::kDimensionsDepthCubeArray:
|
||||
case ValidTextureOverload::kDimensionsStorageRO1d:
|
||||
case ValidTextureOverload::kDimensionsStorageRO1dArray:
|
||||
case ValidTextureOverload::kDimensionsStorageRO2d:
|
||||
case ValidTextureOverload::kDimensionsStorageRO2dArray:
|
||||
case ValidTextureOverload::kDimensionsStorageRO3d:
|
||||
case ValidTextureOverload::kDimensionsStorageWO1d:
|
||||
case ValidTextureOverload::kDimensionsStorageWO1dArray:
|
||||
case ValidTextureOverload::kDimensionsStorageWO2d:
|
||||
case ValidTextureOverload::kDimensionsStorageWO2dArray:
|
||||
case ValidTextureOverload::kDimensionsStorageWO3d:
|
||||
return R"(textureDimensions(texture))";
|
||||
case ValidTextureOverload::kDimensions2dLevel:
|
||||
case ValidTextureOverload::kDimensions2dArrayLevel:
|
||||
case ValidTextureOverload::kDimensions3dLevel:
|
||||
case ValidTextureOverload::kDimensionsCubeLevel:
|
||||
case ValidTextureOverload::kDimensionsCubeArrayLevel:
|
||||
case ValidTextureOverload::kDimensionsDepth2dLevel:
|
||||
case ValidTextureOverload::kDimensionsDepth2dArrayLevel:
|
||||
case ValidTextureOverload::kDimensionsDepthCubeLevel:
|
||||
case ValidTextureOverload::kDimensionsDepthCubeArrayLevel:
|
||||
return R"(textureDimensions(texture, level))";
|
||||
case ValidTextureOverload::kSample1dF32:
|
||||
return R"(textureSample(texture, sampler, coords))";
|
||||
case ValidTextureOverload::kSample1dArrayF32:
|
||||
|
@ -3176,7 +3211,27 @@ TEST_P(TypeDeterminerTextureIntrinsicTest, Call) {
|
|||
ASSERT_TRUE(td()->Determine()) << td()->error();
|
||||
ASSERT_TRUE(td()->DetermineResultType(call)) << td()->error();
|
||||
|
||||
if (std::string(param.function) == "textureStore") {
|
||||
if (std::string(param.function) == "textureDimensions") {
|
||||
switch (param.texture_dimension) {
|
||||
default:
|
||||
FAIL() << "invalid texture dimensions: " << param.texture_dimension;
|
||||
case ast::type::TextureDimension::k1d:
|
||||
case ast::type::TextureDimension::k1dArray:
|
||||
EXPECT_EQ(call->result_type()->type_name(), ty.i32->type_name());
|
||||
break;
|
||||
case ast::type::TextureDimension::k2d:
|
||||
case ast::type::TextureDimension::k2dArray:
|
||||
EXPECT_EQ(call->result_type()->type_name(),
|
||||
ty.vec2<i32>()->type_name());
|
||||
break;
|
||||
case ast::type::TextureDimension::k3d:
|
||||
case ast::type::TextureDimension::kCube:
|
||||
case ast::type::TextureDimension::kCubeArray:
|
||||
EXPECT_EQ(call->result_type()->type_name(),
|
||||
ty.vec3<i32>()->type_name());
|
||||
break;
|
||||
}
|
||||
} else if (std::string(param.function) == "textureStore") {
|
||||
EXPECT_EQ(call->result_type(), ty.void_);
|
||||
} else {
|
||||
switch (param.texture_kind) {
|
||||
|
|
|
@ -736,6 +736,39 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& pre,
|
|||
auto* texture = params[pidx.texture];
|
||||
auto* texture_type = texture->result_type()->UnwrapPtrIfNeeded();
|
||||
|
||||
if (ident->intrinsic() == ast::Intrinsic::kTextureDimensions) {
|
||||
// Declare a variable to hold the texture dimensions
|
||||
auto dims = namer_->GenerateName(kTempNamePrefix);
|
||||
EmitType(pre, expr->result_type(), Symbol());
|
||||
pre << " " << dims << ";" << std::endl;
|
||||
|
||||
// Now call GetDimensions() on the texture object, populating the dims
|
||||
// variable.
|
||||
std::stringstream tex_out;
|
||||
if (!EmitExpression(pre, tex_out, texture)) {
|
||||
return false;
|
||||
}
|
||||
pre << tex_out.str() << ".GetDimensions(";
|
||||
if (pidx.level != kNotUsed) {
|
||||
pre << pidx.level << ", ";
|
||||
}
|
||||
if (auto* vec = expr->result_type()->As<ast::type::Vector>()) {
|
||||
for (uint32_t i = 0; i < vec->size(); i++) {
|
||||
if (i > 0) {
|
||||
pre << ", ";
|
||||
}
|
||||
pre << dims << "[" << i << "]";
|
||||
}
|
||||
} else {
|
||||
pre << dims;
|
||||
}
|
||||
pre << ");";
|
||||
|
||||
// The result of the textureDimensions() call is now the temporary variable.
|
||||
out << dims;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!EmitExpression(pre, out, texture))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -350,10 +350,6 @@ class GeneratorImpl {
|
|||
/// @returns the index string, or blank if unable to generate
|
||||
std::string generate_storage_buffer_index_expression(std::ostream& pre,
|
||||
ast::Expression* expr);
|
||||
/// Generates a name for the prefix
|
||||
/// @param prefix the prefix of the name to generate
|
||||
/// @returns the name
|
||||
std::string generate_name(const std::string& prefix);
|
||||
/// Generates an intrinsic name from the given name
|
||||
/// @param intrinsic the intrinsic to convert to a name
|
||||
/// @returns the intrinsic name or blank on error
|
||||
|
|
|
@ -29,10 +29,77 @@ namespace writer {
|
|||
namespace hlsl {
|
||||
namespace {
|
||||
|
||||
std::string expected_texture_overload(
|
||||
struct ExpectedResult {
|
||||
ExpectedResult(const char* o) : out(o) {} // NOLINT
|
||||
ExpectedResult(const char* p, const char* o) : pre(p), out(o) {}
|
||||
|
||||
std::string pre;
|
||||
std::string out;
|
||||
};
|
||||
|
||||
ExpectedResult expected_texture_overload(
|
||||
ast::intrinsic::test::ValidTextureOverload overload) {
|
||||
using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
|
||||
switch (overload) {
|
||||
case ValidTextureOverload::kDimensions1d:
|
||||
case ValidTextureOverload::kDimensions1dArray:
|
||||
case ValidTextureOverload::kDimensionsStorageRO1d:
|
||||
case ValidTextureOverload::kDimensionsStorageRO1dArray:
|
||||
case ValidTextureOverload::kDimensionsStorageWO1d:
|
||||
case ValidTextureOverload::kDimensionsStorageWO1dArray:
|
||||
return {
|
||||
"int _tint_tmp;\n"
|
||||
"test_texture.GetDimensions(_tint_tmp);",
|
||||
"_tint_tmp",
|
||||
};
|
||||
case ValidTextureOverload::kDimensions2d:
|
||||
case ValidTextureOverload::kDimensions2dArray:
|
||||
case ValidTextureOverload::kDimensionsMultisampled_2d:
|
||||
case ValidTextureOverload::kDimensionsMultisampled_2dArray:
|
||||
case ValidTextureOverload::kDimensionsDepth2d:
|
||||
case ValidTextureOverload::kDimensionsDepth2dArray:
|
||||
case ValidTextureOverload::kDimensionsStorageRO2d:
|
||||
case ValidTextureOverload::kDimensionsStorageRO2dArray:
|
||||
case ValidTextureOverload::kDimensionsStorageWO2d:
|
||||
case ValidTextureOverload::kDimensionsStorageWO2dArray:
|
||||
return {
|
||||
"int2 _tint_tmp;\n"
|
||||
"test_texture.GetDimensions(_tint_tmp[0], _tint_tmp[1]);",
|
||||
"_tint_tmp",
|
||||
};
|
||||
case ValidTextureOverload::kDimensions3d:
|
||||
case ValidTextureOverload::kDimensionsCube:
|
||||
case ValidTextureOverload::kDimensionsCubeArray:
|
||||
case ValidTextureOverload::kDimensionsDepthCube:
|
||||
case ValidTextureOverload::kDimensionsDepthCubeArray:
|
||||
case ValidTextureOverload::kDimensionsStorageRO3d:
|
||||
case ValidTextureOverload::kDimensionsStorageWO3d:
|
||||
return {
|
||||
"int3 _tint_tmp;\n"
|
||||
"test_texture.GetDimensions(_tint_tmp[0], _tint_tmp[1], "
|
||||
"_tint_tmp[2]);",
|
||||
"_tint_tmp",
|
||||
};
|
||||
case ValidTextureOverload::kDimensions2dLevel:
|
||||
case ValidTextureOverload::kDimensions2dArrayLevel:
|
||||
case ValidTextureOverload::kDimensionsDepth2dLevel:
|
||||
case ValidTextureOverload::kDimensionsDepth2dArrayLevel:
|
||||
return {
|
||||
"int2 _tint_tmp;\n"
|
||||
"test_texture.GetDimensions(1, _tint_tmp[0], _tint_tmp[1]);",
|
||||
"_tint_tmp",
|
||||
};
|
||||
case ValidTextureOverload::kDimensions3dLevel:
|
||||
case ValidTextureOverload::kDimensionsCubeLevel:
|
||||
case ValidTextureOverload::kDimensionsCubeArrayLevel:
|
||||
case ValidTextureOverload::kDimensionsDepthCubeLevel:
|
||||
case ValidTextureOverload::kDimensionsDepthCubeArrayLevel:
|
||||
return {
|
||||
"int3 _tint_tmp;\n"
|
||||
"test_texture.GetDimensions(1, _tint_tmp[0], _tint_tmp[1], "
|
||||
"_tint_tmp[2]);",
|
||||
"_tint_tmp",
|
||||
};
|
||||
case ValidTextureOverload::kSample1dF32:
|
||||
return R"(test_texture.Sample(test_sampler, 1.0f))";
|
||||
case ValidTextureOverload::kSample1dArrayF32:
|
||||
|
@ -282,10 +349,10 @@ TEST_P(HlslGeneratorIntrinsicTextureTest, Call) {
|
|||
|
||||
ASSERT_TRUE(gen.EmitExpression(pre, out, call)) << gen.error();
|
||||
|
||||
EXPECT_TRUE(pre_result().empty());
|
||||
|
||||
auto expected = expected_texture_overload(param.overload);
|
||||
EXPECT_EQ(result(), expected);
|
||||
|
||||
EXPECT_EQ(expected.pre, pre_result());
|
||||
EXPECT_EQ(expected.out, result());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
|
|
|
@ -652,6 +652,49 @@ bool GeneratorImpl::EmitTextureCall(ast::CallExpression* expr) {
|
|||
auto& pidx = signature->params.idx;
|
||||
auto const kNotUsed = ast::intrinsic::TextureSignature::Parameters::kNotUsed;
|
||||
|
||||
if (ident->intrinsic() == ast::Intrinsic::kTextureDimensions) {
|
||||
auto get_dim = [&](const char* name) {
|
||||
if (!EmitExpression(params[pidx.texture])) {
|
||||
return false;
|
||||
}
|
||||
out_ << ".get_" << name << "(";
|
||||
if (pidx.level != kNotUsed) {
|
||||
out_ << pidx.level;
|
||||
}
|
||||
out_ << ")";
|
||||
return true;
|
||||
};
|
||||
|
||||
size_t dims = 1;
|
||||
if (auto* vec = expr->result_type()->As<ast::type::Vector>()) {
|
||||
dims = vec->size();
|
||||
}
|
||||
switch (dims) {
|
||||
case 1:
|
||||
get_dim("width");
|
||||
break;
|
||||
case 2:
|
||||
EmitType(expr->result_type(), Symbol());
|
||||
out_ << "(";
|
||||
get_dim("width");
|
||||
out_ << ", ";
|
||||
get_dim("height");
|
||||
out_ << ")";
|
||||
break;
|
||||
case 3:
|
||||
EmitType(expr->result_type(), Symbol());
|
||||
out_ << "(";
|
||||
get_dim("width");
|
||||
out_ << ", ";
|
||||
get_dim("height");
|
||||
out_ << ", ";
|
||||
get_dim("depth");
|
||||
out_ << ")";
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!EmitExpression(params[pidx.texture]))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -33,6 +33,43 @@ std::string expected_texture_overload(
|
|||
ast::intrinsic::test::ValidTextureOverload overload) {
|
||||
using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
|
||||
switch (overload) {
|
||||
case ValidTextureOverload::kDimensions1d:
|
||||
case ValidTextureOverload::kDimensions1dArray:
|
||||
case ValidTextureOverload::kDimensionsStorageRO1d:
|
||||
case ValidTextureOverload::kDimensionsStorageRO1dArray:
|
||||
case ValidTextureOverload::kDimensionsStorageWO1d:
|
||||
case ValidTextureOverload::kDimensionsStorageWO1dArray:
|
||||
return R"(test_texture.get_width())";
|
||||
case ValidTextureOverload::kDimensions2d:
|
||||
case ValidTextureOverload::kDimensions2dArray:
|
||||
case ValidTextureOverload::kDimensionsMultisampled_2d:
|
||||
case ValidTextureOverload::kDimensionsMultisampled_2dArray:
|
||||
case ValidTextureOverload::kDimensionsDepth2d:
|
||||
case ValidTextureOverload::kDimensionsDepth2dArray:
|
||||
case ValidTextureOverload::kDimensionsStorageRO2d:
|
||||
case ValidTextureOverload::kDimensionsStorageRO2dArray:
|
||||
case ValidTextureOverload::kDimensionsStorageWO2d:
|
||||
case ValidTextureOverload::kDimensionsStorageWO2dArray:
|
||||
return R"(int2(test_texture.get_width(), test_texture.get_height()))";
|
||||
case ValidTextureOverload::kDimensions3d:
|
||||
case ValidTextureOverload::kDimensionsCube:
|
||||
case ValidTextureOverload::kDimensionsCubeArray:
|
||||
case ValidTextureOverload::kDimensionsDepthCube:
|
||||
case ValidTextureOverload::kDimensionsDepthCubeArray:
|
||||
case ValidTextureOverload::kDimensionsStorageRO3d:
|
||||
case ValidTextureOverload::kDimensionsStorageWO3d:
|
||||
return R"(int3(test_texture.get_width(), test_texture.get_height(), test_texture.get_depth()))";
|
||||
case ValidTextureOverload::kDimensions2dLevel:
|
||||
case ValidTextureOverload::kDimensions2dArrayLevel:
|
||||
case ValidTextureOverload::kDimensionsDepth2dLevel:
|
||||
case ValidTextureOverload::kDimensionsDepth2dArrayLevel:
|
||||
return R"(int2(test_texture.get_width(1), test_texture.get_height(1)))";
|
||||
case ValidTextureOverload::kDimensions3dLevel:
|
||||
case ValidTextureOverload::kDimensionsCubeLevel:
|
||||
case ValidTextureOverload::kDimensionsCubeArrayLevel:
|
||||
case ValidTextureOverload::kDimensionsDepthCubeLevel:
|
||||
case ValidTextureOverload::kDimensionsDepthCubeArrayLevel:
|
||||
return R"(int3(test_texture.get_width(1), test_texture.get_height(1), test_texture.get_depth(1)))";
|
||||
case ValidTextureOverload::kSample1dF32:
|
||||
return R"(test_texture.sample(test_sampler, 1.0f))";
|
||||
case ValidTextureOverload::kSample1dArrayF32:
|
||||
|
@ -275,7 +312,7 @@ TEST_P(MslGeneratorIntrinsicTextureTest, Call) {
|
|||
ASSERT_TRUE(gen.EmitExpression(call)) << gen.error();
|
||||
|
||||
auto expected = expected_texture_overload(param.overload);
|
||||
EXPECT_EQ(gen.result(), expected);
|
||||
EXPECT_EQ(expected, gen.result());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
|
|
|
@ -1850,6 +1850,15 @@ uint32_t Builder::GenerateIntrinsic(ast::IdentifierExpression* ident,
|
|||
|
||||
auto intrinsic = ident->intrinsic();
|
||||
|
||||
if (ast::intrinsic::IsFineDerivative(intrinsic) ||
|
||||
ast::intrinsic::IsCoarseDerivative(intrinsic)) {
|
||||
push_capability(SpvCapabilityDerivativeControl);
|
||||
}
|
||||
|
||||
if (ast::intrinsic::IsImageQueryIntrinsic(intrinsic)) {
|
||||
push_capability(SpvCapabilityImageQuery);
|
||||
}
|
||||
|
||||
if (ast::intrinsic::IsTextureIntrinsic(intrinsic)) {
|
||||
if (!GenerateTextureIntrinsic(ident, call, Operand::Int(result_type_id),
|
||||
result)) {
|
||||
|
@ -1860,11 +1869,6 @@ uint32_t Builder::GenerateIntrinsic(ast::IdentifierExpression* ident,
|
|||
|
||||
OperandList params = {Operand::Int(result_type_id), result};
|
||||
|
||||
if (ast::intrinsic::IsFineDerivative(intrinsic) ||
|
||||
ast::intrinsic::IsCoarseDerivative(intrinsic)) {
|
||||
push_capability(SpvCapabilityDerivativeControl);
|
||||
}
|
||||
|
||||
spv::Op op = spv::Op::OpNop;
|
||||
if (intrinsic == ast::Intrinsic::kAny) {
|
||||
op = spv::Op::OpAny;
|
||||
|
@ -1982,8 +1986,8 @@ uint32_t Builder::GenerateIntrinsic(ast::IdentifierExpression* ident,
|
|||
|
||||
bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
|
||||
ast::CallExpression* call,
|
||||
spirv::Operand result_type,
|
||||
spirv::Operand result_id) {
|
||||
Operand result_type,
|
||||
Operand result_id) {
|
||||
auto* texture_type =
|
||||
call->params()[0]->result_type()->UnwrapAll()->As<ast::type::Texture>();
|
||||
|
||||
|
@ -2008,22 +2012,26 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
|
|||
return Operand::Int(val_id);
|
||||
};
|
||||
|
||||
// Custom function to call after the texture-intrinsic op has been generated.
|
||||
std::function<bool()> post_emission = [] { return true; };
|
||||
|
||||
// Populate the spirv_params with common parameters
|
||||
OperandList spirv_params;
|
||||
spirv_params.reserve(8); // Enough to fit most parameter lists
|
||||
if (ident->intrinsic() != ast::Intrinsic::kTextureStore) {
|
||||
spirv_params.emplace_back(std::move(result_type));
|
||||
spirv_params.emplace_back(std::move(result_id));
|
||||
}
|
||||
|
||||
// Extra image operands, appended to spirv_params.
|
||||
struct ImageOperand {
|
||||
SpvImageOperandsMask mask;
|
||||
tint::writer::spirv::Operand operand;
|
||||
Operand operand;
|
||||
};
|
||||
std::vector<ImageOperand> image_operands;
|
||||
image_operands.reserve(4); // Enough to fit most parameter lists
|
||||
|
||||
auto append_result_type_and_id_to_spirv_params = [&]() {
|
||||
spirv_params.emplace_back(std::move(result_type));
|
||||
spirv_params.emplace_back(std::move(result_id));
|
||||
};
|
||||
|
||||
auto append_coords_to_spirv_params = [&]() -> bool {
|
||||
if (pidx.array_index != kNotUsed) {
|
||||
// Array index needs to be appended to the coordinates.
|
||||
|
@ -2062,10 +2070,67 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
|
|||
};
|
||||
|
||||
switch (ident->intrinsic()) {
|
||||
case ast::Intrinsic::kTextureDimensions: {
|
||||
if (ast::type::IsTextureArray(texture_type->dim())) {
|
||||
// OpImageQuerySize[Lod] will append another element to the returned
|
||||
// vector describing the number of array elements. textureDimensions()
|
||||
// does not include this in the returned vector, so it needs to be
|
||||
// stripped from the resulting vector.
|
||||
auto unstripped_result = result_op();
|
||||
|
||||
ast::type::Type* unstripped_result_type;
|
||||
if (auto* v = call->result_type()->As<ast::type::Vector>()) {
|
||||
unstripped_result_type =
|
||||
mod_->create<ast::type::Vector>(v->type(), v->size() + 1);
|
||||
post_emission = [=] {
|
||||
// Swizzle the unstripped vector to form a vec2 or vec3
|
||||
OperandList operands{
|
||||
result_type,
|
||||
result_id,
|
||||
unstripped_result,
|
||||
unstripped_result,
|
||||
};
|
||||
for (uint32_t i = 0; i < v->size(); i++) {
|
||||
operands.emplace_back(Operand::Int(i));
|
||||
}
|
||||
return push_function_inst(spv::Op::OpVectorShuffle, operands);
|
||||
};
|
||||
} else {
|
||||
unstripped_result_type =
|
||||
mod_->create<ast::type::Vector>(call->result_type(), 2);
|
||||
post_emission = [=] {
|
||||
// Extract the first element of the unstripped vec2 to form a scalar
|
||||
return push_function_inst(
|
||||
spv::Op::OpCompositeExtract,
|
||||
{result_type, result_id, unstripped_result, Operand::Int(0)});
|
||||
};
|
||||
}
|
||||
|
||||
auto unstripped_result_type_id =
|
||||
GenerateTypeIfNeeded(unstripped_result_type);
|
||||
if (unstripped_result_type_id == 0) {
|
||||
return false;
|
||||
}
|
||||
spirv_params.emplace_back(Operand::Int(unstripped_result_type_id));
|
||||
spirv_params.emplace_back(unstripped_result);
|
||||
} else {
|
||||
append_result_type_and_id_to_spirv_params();
|
||||
}
|
||||
|
||||
spirv_params.emplace_back(gen_param(pidx.texture));
|
||||
if (pidx.level != kNotUsed) {
|
||||
op = spv::Op::OpImageQuerySizeLod;
|
||||
spirv_params.emplace_back(gen_param(pidx.level));
|
||||
} else {
|
||||
op = spv::Op::OpImageQuerySize;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ast::Intrinsic::kTextureLoad: {
|
||||
op = texture_type->Is<ast::type::StorageTexture>()
|
||||
? spv::Op::OpImageRead
|
||||
: spv::Op::OpImageFetch;
|
||||
append_result_type_and_id_to_spirv_params();
|
||||
spirv_params.emplace_back(gen_param(pidx.texture));
|
||||
if (!append_coords_to_spirv_params()) {
|
||||
return false;
|
||||
|
@ -2094,6 +2159,7 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
|
|||
}
|
||||
case ast::Intrinsic::kTextureSample: {
|
||||
op = spv::Op::OpImageSampleImplicitLod;
|
||||
append_result_type_and_id_to_spirv_params();
|
||||
if (!append_image_and_coords_to_spirv_params()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2101,6 +2167,7 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
|
|||
}
|
||||
case ast::Intrinsic::kTextureSampleBias: {
|
||||
op = spv::Op::OpImageSampleImplicitLod;
|
||||
append_result_type_and_id_to_spirv_params();
|
||||
if (!append_image_and_coords_to_spirv_params()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2111,6 +2178,7 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
|
|||
}
|
||||
case ast::Intrinsic::kTextureSampleLevel: {
|
||||
op = spv::Op::OpImageSampleExplicitLod;
|
||||
append_result_type_and_id_to_spirv_params();
|
||||
if (!append_image_and_coords_to_spirv_params()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2121,6 +2189,7 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
|
|||
}
|
||||
case ast::Intrinsic::kTextureSampleGrad: {
|
||||
op = spv::Op::OpImageSampleExplicitLod;
|
||||
append_result_type_and_id_to_spirv_params();
|
||||
if (!append_image_and_coords_to_spirv_params()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2134,6 +2203,7 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
|
|||
}
|
||||
case ast::Intrinsic::kTextureSampleCompare: {
|
||||
op = spv::Op::OpImageSampleDrefExplicitLod;
|
||||
append_result_type_and_id_to_spirv_params();
|
||||
if (!append_image_and_coords_to_spirv_params()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2175,7 +2245,11 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
|
|||
return false;
|
||||
}
|
||||
|
||||
return push_function_inst(op, spirv_params);
|
||||
if (!push_function_inst(op, spirv_params)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return post_emission();
|
||||
}
|
||||
|
||||
uint32_t Builder::GenerateSampledImage(ast::type::Type* texture_type,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue