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) {
|
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::kTextureSampleLevel ||
|
||||||
i == Intrinsic::kTextureSampleBias ||
|
i == Intrinsic::kTextureSampleBias ||
|
||||||
i == Intrinsic::kTextureSampleCompare ||
|
i == Intrinsic::kTextureSampleCompare ||
|
||||||
i == Intrinsic::kTextureSampleGrad || i == Intrinsic::kTextureStore;
|
i == Intrinsic::kTextureSampleGrad || i == Intrinsic::kTextureStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsImageQueryIntrinsic(Intrinsic i) {
|
||||||
|
return i == ast::Intrinsic::kTextureDimensions;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace intrinsic
|
} // namespace intrinsic
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
|
@ -84,6 +84,7 @@ enum class Intrinsic {
|
||||||
kStep,
|
kStep,
|
||||||
kTan,
|
kTan,
|
||||||
kTanh,
|
kTanh,
|
||||||
|
kTextureDimensions,
|
||||||
kTextureLoad,
|
kTextureLoad,
|
||||||
kTextureSample,
|
kTextureSample,
|
||||||
kTextureSampleBias,
|
kTextureSampleBias,
|
||||||
|
@ -187,6 +188,11 @@ bool IsFloatClassificationIntrinsic(Intrinsic i);
|
||||||
/// @returns true if the given `i` is a texture operation intrinsic
|
/// @returns true if the given `i` is a texture operation intrinsic
|
||||||
bool IsTextureIntrinsic(Intrinsic i);
|
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 intrinsic
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
|
@ -186,6 +186,344 @@ ast::Variable* TextureOverloadCase::buildSamplerVariable(
|
||||||
|
|
||||||
std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
|
std::vector<TextureOverloadCase> TextureOverloadCase::ValidCases() {
|
||||||
return {
|
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,
|
ValidTextureOverload::kSample1dF32,
|
||||||
"textureSample(t : texture_1d<f32>,\n"
|
"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
|
/// Non-exhaustive list of valid texture overloads
|
||||||
enum class ValidTextureOverload {
|
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,
|
kSample1dF32,
|
||||||
kSample1dArrayF32,
|
kSample1dArrayF32,
|
||||||
kSample2dF32,
|
kSample2dF32,
|
||||||
|
|
|
@ -56,6 +56,22 @@ std::ostream& operator<<(std::ostream& out, TextureDimension dim) {
|
||||||
return out;
|
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(TextureDimension dim) : dim_(dim) {}
|
||||||
|
|
||||||
Texture::Texture(Texture&&) = default;
|
Texture::Texture(Texture&&) = default;
|
||||||
|
|
|
@ -42,6 +42,10 @@ enum class TextureDimension {
|
||||||
};
|
};
|
||||||
std::ostream& operator<<(std::ostream& out, TextureDimension dim);
|
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.
|
/// A texture type.
|
||||||
class Texture : public Castable<Texture, Type> {
|
class Texture : public Castable<Texture, Type> {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -556,18 +556,15 @@ bool TypeDeterminer::DetermineIntrinsic(ast::IdentifierExpression* ident,
|
||||||
->UnwrapPtrIfNeeded()
|
->UnwrapPtrIfNeeded()
|
||||||
->As<ast::type::Texture>();
|
->As<ast::type::Texture>();
|
||||||
|
|
||||||
bool is_array = false;
|
bool is_array = ast::type::IsTextureArray(texture->dim());
|
||||||
bool is_multisampled = texture->Is<ast::type::MultisampledTexture>();
|
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()) {
|
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:
|
case ast::Intrinsic::kTextureLoad:
|
||||||
param.idx.texture = param.count++;
|
param.idx.texture = param.count++;
|
||||||
param.idx.coords = param.count++;
|
param.idx.coords = param.count++;
|
||||||
|
@ -671,7 +668,27 @@ bool TypeDeterminer::DetermineIntrinsic(ast::IdentifierExpression* ident,
|
||||||
|
|
||||||
// Set the function return type
|
// Set the function return type
|
||||||
ast::type::Type* return_type = nullptr;
|
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>();
|
return_type = mod_->create<ast::type::Void>();
|
||||||
} else {
|
} else {
|
||||||
if (texture->Is<ast::type::DepthTexture>()) {
|
if (texture->Is<ast::type::DepthTexture>()) {
|
||||||
|
@ -1025,6 +1042,8 @@ bool TypeDeterminer::SetIntrinsicIfNeeded(ast::IdentifierExpression* ident) {
|
||||||
ident->set_intrinsic(ast::Intrinsic::kTan);
|
ident->set_intrinsic(ast::Intrinsic::kTan);
|
||||||
} else if (name == "tanh") {
|
} else if (name == "tanh") {
|
||||||
ident->set_intrinsic(ast::Intrinsic::kTanh);
|
ident->set_intrinsic(ast::Intrinsic::kTanh);
|
||||||
|
} else if (name == "textureDimensions") {
|
||||||
|
ident->set_intrinsic(ast::Intrinsic::kTextureDimensions);
|
||||||
} else if (name == "textureLoad") {
|
} else if (name == "textureLoad") {
|
||||||
ident->set_intrinsic(ast::Intrinsic::kTextureLoad);
|
ident->set_intrinsic(ast::Intrinsic::kTextureLoad);
|
||||||
} else if (name == "textureStore") {
|
} else if (name == "textureStore") {
|
||||||
|
|
|
@ -1812,6 +1812,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
IntrinsicData{"step", ast::Intrinsic::kStep},
|
IntrinsicData{"step", ast::Intrinsic::kStep},
|
||||||
IntrinsicData{"tan", ast::Intrinsic::kTan},
|
IntrinsicData{"tan", ast::Intrinsic::kTan},
|
||||||
IntrinsicData{"tanh", ast::Intrinsic::kTanh},
|
IntrinsicData{"tanh", ast::Intrinsic::kTanh},
|
||||||
|
IntrinsicData{"textureDimensions", ast::Intrinsic::kTextureDimensions},
|
||||||
IntrinsicData{"textureLoad", ast::Intrinsic::kTextureLoad},
|
IntrinsicData{"textureLoad", ast::Intrinsic::kTextureLoad},
|
||||||
IntrinsicData{"textureSample", ast::Intrinsic::kTextureSample},
|
IntrinsicData{"textureSample", ast::Intrinsic::kTextureSample},
|
||||||
IntrinsicData{"textureSampleBias", ast::Intrinsic::kTextureSampleBias},
|
IntrinsicData{"textureSampleBias", ast::Intrinsic::kTextureSampleBias},
|
||||||
|
@ -2953,6 +2954,40 @@ const char* expected_texture_overload(
|
||||||
ast::intrinsic::test::ValidTextureOverload overload) {
|
ast::intrinsic::test::ValidTextureOverload overload) {
|
||||||
using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
|
using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
|
||||||
switch (overload) {
|
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:
|
case ValidTextureOverload::kSample1dF32:
|
||||||
return R"(textureSample(texture, sampler, coords))";
|
return R"(textureSample(texture, sampler, coords))";
|
||||||
case ValidTextureOverload::kSample1dArrayF32:
|
case ValidTextureOverload::kSample1dArrayF32:
|
||||||
|
@ -3176,7 +3211,27 @@ TEST_P(TypeDeterminerTextureIntrinsicTest, Call) {
|
||||||
ASSERT_TRUE(td()->Determine()) << td()->error();
|
ASSERT_TRUE(td()->Determine()) << td()->error();
|
||||||
ASSERT_TRUE(td()->DetermineResultType(call)) << 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_);
|
EXPECT_EQ(call->result_type(), ty.void_);
|
||||||
} else {
|
} else {
|
||||||
switch (param.texture_kind) {
|
switch (param.texture_kind) {
|
||||||
|
|
|
@ -736,6 +736,39 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& pre,
|
||||||
auto* texture = params[pidx.texture];
|
auto* texture = params[pidx.texture];
|
||||||
auto* texture_type = texture->result_type()->UnwrapPtrIfNeeded();
|
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))
|
if (!EmitExpression(pre, out, texture))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -350,10 +350,6 @@ class GeneratorImpl {
|
||||||
/// @returns the index string, or blank if unable to generate
|
/// @returns the index string, or blank if unable to generate
|
||||||
std::string generate_storage_buffer_index_expression(std::ostream& pre,
|
std::string generate_storage_buffer_index_expression(std::ostream& pre,
|
||||||
ast::Expression* expr);
|
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
|
/// Generates an intrinsic name from the given name
|
||||||
/// @param intrinsic the intrinsic to convert to a name
|
/// @param intrinsic the intrinsic to convert to a name
|
||||||
/// @returns the intrinsic name or blank on error
|
/// @returns the intrinsic name or blank on error
|
||||||
|
|
|
@ -29,10 +29,77 @@ namespace writer {
|
||||||
namespace hlsl {
|
namespace hlsl {
|
||||||
namespace {
|
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) {
|
ast::intrinsic::test::ValidTextureOverload overload) {
|
||||||
using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
|
using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
|
||||||
switch (overload) {
|
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:
|
case ValidTextureOverload::kSample1dF32:
|
||||||
return R"(test_texture.Sample(test_sampler, 1.0f))";
|
return R"(test_texture.Sample(test_sampler, 1.0f))";
|
||||||
case ValidTextureOverload::kSample1dArrayF32:
|
case ValidTextureOverload::kSample1dArrayF32:
|
||||||
|
@ -282,10 +349,10 @@ TEST_P(HlslGeneratorIntrinsicTextureTest, Call) {
|
||||||
|
|
||||||
ASSERT_TRUE(gen.EmitExpression(pre, out, call)) << gen.error();
|
ASSERT_TRUE(gen.EmitExpression(pre, out, call)) << gen.error();
|
||||||
|
|
||||||
EXPECT_TRUE(pre_result().empty());
|
|
||||||
|
|
||||||
auto expected = expected_texture_overload(param.overload);
|
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(
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
|
|
@ -652,6 +652,49 @@ bool GeneratorImpl::EmitTextureCall(ast::CallExpression* expr) {
|
||||||
auto& pidx = signature->params.idx;
|
auto& pidx = signature->params.idx;
|
||||||
auto const kNotUsed = ast::intrinsic::TextureSignature::Parameters::kNotUsed;
|
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]))
|
if (!EmitExpression(params[pidx.texture]))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,43 @@ std::string expected_texture_overload(
|
||||||
ast::intrinsic::test::ValidTextureOverload overload) {
|
ast::intrinsic::test::ValidTextureOverload overload) {
|
||||||
using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
|
using ValidTextureOverload = ast::intrinsic::test::ValidTextureOverload;
|
||||||
switch (overload) {
|
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:
|
case ValidTextureOverload::kSample1dF32:
|
||||||
return R"(test_texture.sample(test_sampler, 1.0f))";
|
return R"(test_texture.sample(test_sampler, 1.0f))";
|
||||||
case ValidTextureOverload::kSample1dArrayF32:
|
case ValidTextureOverload::kSample1dArrayF32:
|
||||||
|
@ -275,7 +312,7 @@ TEST_P(MslGeneratorIntrinsicTextureTest, Call) {
|
||||||
ASSERT_TRUE(gen.EmitExpression(call)) << gen.error();
|
ASSERT_TRUE(gen.EmitExpression(call)) << gen.error();
|
||||||
|
|
||||||
auto expected = expected_texture_overload(param.overload);
|
auto expected = expected_texture_overload(param.overload);
|
||||||
EXPECT_EQ(gen.result(), expected);
|
EXPECT_EQ(expected, gen.result());
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
|
|
@ -1850,6 +1850,15 @@ uint32_t Builder::GenerateIntrinsic(ast::IdentifierExpression* ident,
|
||||||
|
|
||||||
auto intrinsic = ident->intrinsic();
|
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 (ast::intrinsic::IsTextureIntrinsic(intrinsic)) {
|
||||||
if (!GenerateTextureIntrinsic(ident, call, Operand::Int(result_type_id),
|
if (!GenerateTextureIntrinsic(ident, call, Operand::Int(result_type_id),
|
||||||
result)) {
|
result)) {
|
||||||
|
@ -1860,11 +1869,6 @@ uint32_t Builder::GenerateIntrinsic(ast::IdentifierExpression* ident,
|
||||||
|
|
||||||
OperandList params = {Operand::Int(result_type_id), result};
|
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;
|
spv::Op op = spv::Op::OpNop;
|
||||||
if (intrinsic == ast::Intrinsic::kAny) {
|
if (intrinsic == ast::Intrinsic::kAny) {
|
||||||
op = spv::Op::OpAny;
|
op = spv::Op::OpAny;
|
||||||
|
@ -1982,8 +1986,8 @@ uint32_t Builder::GenerateIntrinsic(ast::IdentifierExpression* ident,
|
||||||
|
|
||||||
bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
|
bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
|
||||||
ast::CallExpression* call,
|
ast::CallExpression* call,
|
||||||
spirv::Operand result_type,
|
Operand result_type,
|
||||||
spirv::Operand result_id) {
|
Operand result_id) {
|
||||||
auto* texture_type =
|
auto* texture_type =
|
||||||
call->params()[0]->result_type()->UnwrapAll()->As<ast::type::Texture>();
|
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);
|
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
|
// Populate the spirv_params with common parameters
|
||||||
OperandList spirv_params;
|
OperandList spirv_params;
|
||||||
spirv_params.reserve(8); // Enough to fit most parameter lists
|
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.
|
// Extra image operands, appended to spirv_params.
|
||||||
struct ImageOperand {
|
struct ImageOperand {
|
||||||
SpvImageOperandsMask mask;
|
SpvImageOperandsMask mask;
|
||||||
tint::writer::spirv::Operand operand;
|
Operand operand;
|
||||||
};
|
};
|
||||||
std::vector<ImageOperand> image_operands;
|
std::vector<ImageOperand> image_operands;
|
||||||
image_operands.reserve(4); // Enough to fit most parameter lists
|
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 {
|
auto append_coords_to_spirv_params = [&]() -> bool {
|
||||||
if (pidx.array_index != kNotUsed) {
|
if (pidx.array_index != kNotUsed) {
|
||||||
// Array index needs to be appended to the coordinates.
|
// Array index needs to be appended to the coordinates.
|
||||||
|
@ -2062,10 +2070,67 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (ident->intrinsic()) {
|
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: {
|
case ast::Intrinsic::kTextureLoad: {
|
||||||
op = texture_type->Is<ast::type::StorageTexture>()
|
op = texture_type->Is<ast::type::StorageTexture>()
|
||||||
? spv::Op::OpImageRead
|
? spv::Op::OpImageRead
|
||||||
: spv::Op::OpImageFetch;
|
: spv::Op::OpImageFetch;
|
||||||
|
append_result_type_and_id_to_spirv_params();
|
||||||
spirv_params.emplace_back(gen_param(pidx.texture));
|
spirv_params.emplace_back(gen_param(pidx.texture));
|
||||||
if (!append_coords_to_spirv_params()) {
|
if (!append_coords_to_spirv_params()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -2094,6 +2159,7 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
|
||||||
}
|
}
|
||||||
case ast::Intrinsic::kTextureSample: {
|
case ast::Intrinsic::kTextureSample: {
|
||||||
op = spv::Op::OpImageSampleImplicitLod;
|
op = spv::Op::OpImageSampleImplicitLod;
|
||||||
|
append_result_type_and_id_to_spirv_params();
|
||||||
if (!append_image_and_coords_to_spirv_params()) {
|
if (!append_image_and_coords_to_spirv_params()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2101,6 +2167,7 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
|
||||||
}
|
}
|
||||||
case ast::Intrinsic::kTextureSampleBias: {
|
case ast::Intrinsic::kTextureSampleBias: {
|
||||||
op = spv::Op::OpImageSampleImplicitLod;
|
op = spv::Op::OpImageSampleImplicitLod;
|
||||||
|
append_result_type_and_id_to_spirv_params();
|
||||||
if (!append_image_and_coords_to_spirv_params()) {
|
if (!append_image_and_coords_to_spirv_params()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2111,6 +2178,7 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
|
||||||
}
|
}
|
||||||
case ast::Intrinsic::kTextureSampleLevel: {
|
case ast::Intrinsic::kTextureSampleLevel: {
|
||||||
op = spv::Op::OpImageSampleExplicitLod;
|
op = spv::Op::OpImageSampleExplicitLod;
|
||||||
|
append_result_type_and_id_to_spirv_params();
|
||||||
if (!append_image_and_coords_to_spirv_params()) {
|
if (!append_image_and_coords_to_spirv_params()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2121,6 +2189,7 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
|
||||||
}
|
}
|
||||||
case ast::Intrinsic::kTextureSampleGrad: {
|
case ast::Intrinsic::kTextureSampleGrad: {
|
||||||
op = spv::Op::OpImageSampleExplicitLod;
|
op = spv::Op::OpImageSampleExplicitLod;
|
||||||
|
append_result_type_and_id_to_spirv_params();
|
||||||
if (!append_image_and_coords_to_spirv_params()) {
|
if (!append_image_and_coords_to_spirv_params()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2134,6 +2203,7 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
|
||||||
}
|
}
|
||||||
case ast::Intrinsic::kTextureSampleCompare: {
|
case ast::Intrinsic::kTextureSampleCompare: {
|
||||||
op = spv::Op::OpImageSampleDrefExplicitLod;
|
op = spv::Op::OpImageSampleDrefExplicitLod;
|
||||||
|
append_result_type_and_id_to_spirv_params();
|
||||||
if (!append_image_and_coords_to_spirv_params()) {
|
if (!append_image_and_coords_to_spirv_params()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2175,7 +2245,11 @@ bool Builder::GenerateTextureIntrinsic(ast::IdentifierExpression* ident,
|
||||||
return false;
|
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,
|
uint32_t Builder::GenerateSampledImage(ast::type::Type* texture_type,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue