spirv-reader: support textureSampleCompareLevel
- Translates from OpImageSampleDrefExplicitLod, but the Lod must be a constant 0, or the reader issues an error. The requirement for Lod 0 is a constraint from Metal, inherited by WGSL. Fixed: tint:425, tint:482 Change-Id: I8fdf10dbd9c5ac3e24398519a28202c84677c38d Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/51803 Commit-Queue: David Neto <dneto@google.com> Auto-Submit: David Neto <dneto@google.com> Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
a53a3b8c19
commit
9d555d1621
|
@ -3262,16 +3262,10 @@ bool FunctionEmitter::EmitStatement(const spvtools::opt::Instruction& inst) {
|
||||||
// Handle exceptional cases
|
// Handle exceptional cases
|
||||||
switch (GetSkipReason(ptr_id)) {
|
switch (GetSkipReason(ptr_id)) {
|
||||||
case SkipReason::kPointSizeBuiltinPointer:
|
case SkipReason::kPointSizeBuiltinPointer:
|
||||||
if (const auto* c = constant_mgr_->FindDeclaredConstant(value_id)) {
|
if (IsFloatOne(value_id)) {
|
||||||
// If we're writing a constant 1.0, then skip the write. That's all
|
|
||||||
// that WebGPU handles.
|
|
||||||
auto* ct = c->type();
|
|
||||||
if (ct->AsFloat() && (ct->AsFloat()->width() == 32) &&
|
|
||||||
(c->GetFloat() == 1.0f)) {
|
|
||||||
// Don't store to PointSize
|
// Don't store to PointSize
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return Fail() << "cannot store a value other than constant 1.0 to "
|
return Fail() << "cannot store a value other than constant 1.0 to "
|
||||||
"PointSize builtin: "
|
"PointSize builtin: "
|
||||||
<< inst.PrettyPrint();
|
<< inst.PrettyPrint();
|
||||||
|
@ -4843,6 +4837,17 @@ bool FunctionEmitter::EmitImageAccess(const spvtools::opt::Instruction& inst) {
|
||||||
if (use_level_of_detail_suffix) {
|
if (use_level_of_detail_suffix) {
|
||||||
builtin_name += "Level";
|
builtin_name += "Level";
|
||||||
}
|
}
|
||||||
|
if (is_dref_sample) {
|
||||||
|
// Metal only supports Lod = 0 for comparison sampling without
|
||||||
|
// derivatives.
|
||||||
|
if (!IsFloatZero(inst.GetSingleWordInOperand(arg_index))) {
|
||||||
|
return Fail() << "WGSL comparison sampling without derivatives "
|
||||||
|
"requires level-of-detail 0.0"
|
||||||
|
<< inst.PrettyPrint();
|
||||||
|
}
|
||||||
|
// Don't generate the Lod argument.
|
||||||
|
} else {
|
||||||
|
// Generate the Lod argument.
|
||||||
TypedExpression lod = MakeOperand(inst, arg_index);
|
TypedExpression lod = MakeOperand(inst, arg_index);
|
||||||
// When sampling from a depth texture, the Lod operand must be an I32.
|
// When sampling from a depth texture, the Lod operand must be an I32.
|
||||||
if (texture_type->Is<DepthTexture>()) {
|
if (texture_type->Is<DepthTexture>()) {
|
||||||
|
@ -4850,6 +4855,8 @@ bool FunctionEmitter::EmitImageAccess(const spvtools::opt::Instruction& inst) {
|
||||||
lod = ToI32(lod);
|
lod = ToI32(lod);
|
||||||
}
|
}
|
||||||
params.push_back(lod.expr);
|
params.push_back(lod.expr);
|
||||||
|
}
|
||||||
|
|
||||||
image_operands_mask ^= SpvImageOperandsLodMask;
|
image_operands_mask ^= SpvImageOperandsLodMask;
|
||||||
arg_index++;
|
arg_index++;
|
||||||
} else if ((opcode == SpvOpImageFetch) &&
|
} else if ((opcode == SpvOpImageFetch) &&
|
||||||
|
@ -5466,6 +5473,28 @@ TypedExpression FunctionEmitter::Dereference(TypedExpression expr) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FunctionEmitter::IsFloatZero(uint32_t value_id) {
|
||||||
|
if (const auto* c = constant_mgr_->FindDeclaredConstant(value_id)) {
|
||||||
|
if (const auto* float_const = c->AsFloatConstant()) {
|
||||||
|
return 0.0f == float_const->GetFloatValue();
|
||||||
|
}
|
||||||
|
if (c->AsNullConstant()) {
|
||||||
|
// Valid SPIR-V requires it to be a float value anyway.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FunctionEmitter::IsFloatOne(uint32_t value_id) {
|
||||||
|
if (const auto* c = constant_mgr_->FindDeclaredConstant(value_id)) {
|
||||||
|
if (const auto* float_const = c->AsFloatConstant()) {
|
||||||
|
return 1.0f == float_const->GetFloatValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
FunctionEmitter::FunctionDeclaration::FunctionDeclaration() = default;
|
FunctionEmitter::FunctionDeclaration::FunctionDeclaration() = default;
|
||||||
FunctionEmitter::FunctionDeclaration::~FunctionDeclaration() = default;
|
FunctionEmitter::FunctionDeclaration::~FunctionDeclaration() = default;
|
||||||
|
|
||||||
|
|
|
@ -851,6 +851,11 @@ class FunctionEmitter {
|
||||||
/// @returns the value itself, or converted to signed integral
|
/// @returns the value itself, or converted to signed integral
|
||||||
TypedExpression ToSignedIfUnsigned(TypedExpression value);
|
TypedExpression ToSignedIfUnsigned(TypedExpression value);
|
||||||
|
|
||||||
|
/// Returns true if the given SPIR-V id represents a constant float 0.
|
||||||
|
bool IsFloatZero(uint32_t value_id);
|
||||||
|
/// Returns true if the given SPIR-V id represents a constant float 1.
|
||||||
|
bool IsFloatOne(uint32_t value_id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// FunctionDeclaration contains the parsed information for a function header.
|
/// FunctionDeclaration contains the parsed information for a function header.
|
||||||
struct FunctionDeclaration {
|
struct FunctionDeclaration {
|
||||||
|
|
|
@ -90,6 +90,7 @@ std::string CommonBasicTypes() {
|
||||||
%v4float = OpTypeVector %float 4
|
%v4float = OpTypeVector %float 4
|
||||||
|
|
||||||
%float_null = OpConstantNull %float
|
%float_null = OpConstantNull %float
|
||||||
|
%float_0 = OpConstant %float 0
|
||||||
%float_1 = OpConstant %float 1
|
%float_1 = OpConstant %float 1
|
||||||
%float_2 = OpConstant %float 2
|
%float_2 = OpConstant %float 2
|
||||||
%float_3 = OpConstant %float 3
|
%float_3 = OpConstant %float 3
|
||||||
|
@ -932,8 +933,6 @@ TEST_P(SpvParserHandleTest_RegisterHandleUsage_SampledImage, Variable) {
|
||||||
p->DeliberatelyInvalidSpirv();
|
p->DeliberatelyInvalidSpirv();
|
||||||
}
|
}
|
||||||
if (inst.find("ImageSampleDrefExplicitLod") != std::string::npos) {
|
if (inst.find("ImageSampleDrefExplicitLod") != std::string::npos) {
|
||||||
// WGSL does not support querying image level of detail.
|
|
||||||
// So don't emit them as part of a "passing" corpus.
|
|
||||||
p->SkipDumpingPending("crbug.com/tint/425"); // gpuweb issue #1319
|
p->SkipDumpingPending("crbug.com/tint/425"); // gpuweb issue #1319
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2259,6 +2258,253 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
)
|
)
|
||||||
})"}));
|
})"}));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
ImageSampleDrefExplicitLod,
|
||||||
|
SpvParserHandleTest_SampledImageAccessTest,
|
||||||
|
// Lod must be float constant 0 due to a Metal constraint.
|
||||||
|
// Another test checks cases where the Lod is not float constant 0.
|
||||||
|
::testing::Values(
|
||||||
|
// 2D
|
||||||
|
ImageAccessCase{"%float 2D 1 0 0 1 Unknown",
|
||||||
|
"%result = OpImageSampleDrefExplicitLod "
|
||||||
|
"%float %sampled_image %coords12 %depth Lod %float_0",
|
||||||
|
R"(
|
||||||
|
Variable{
|
||||||
|
Decorations{
|
||||||
|
GroupDecoration{0}
|
||||||
|
BindingDecoration{0}
|
||||||
|
}
|
||||||
|
x_10
|
||||||
|
none
|
||||||
|
__sampler_comparison
|
||||||
|
}
|
||||||
|
Variable{
|
||||||
|
Decorations{
|
||||||
|
GroupDecoration{2}
|
||||||
|
BindingDecoration{1}
|
||||||
|
}
|
||||||
|
x_20
|
||||||
|
none
|
||||||
|
__depth_texture_2d
|
||||||
|
})",
|
||||||
|
R"(
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{textureSampleCompareLevel}
|
||||||
|
(
|
||||||
|
Identifier[not set]{x_20}
|
||||||
|
Identifier[not set]{x_10}
|
||||||
|
Identifier[not set]{coords12}
|
||||||
|
ScalarConstructor[not set]{0.200000}
|
||||||
|
)
|
||||||
|
})"},
|
||||||
|
// 2D array
|
||||||
|
ImageAccessCase{"%float 2D 1 1 0 1 Unknown",
|
||||||
|
"%result = OpImageSampleDrefExplicitLod "
|
||||||
|
"%float %sampled_image %coords123 %depth Lod %float_0",
|
||||||
|
R"(
|
||||||
|
Variable{
|
||||||
|
Decorations{
|
||||||
|
GroupDecoration{0}
|
||||||
|
BindingDecoration{0}
|
||||||
|
}
|
||||||
|
x_10
|
||||||
|
none
|
||||||
|
__sampler_comparison
|
||||||
|
}
|
||||||
|
Variable{
|
||||||
|
Decorations{
|
||||||
|
GroupDecoration{2}
|
||||||
|
BindingDecoration{1}
|
||||||
|
}
|
||||||
|
x_20
|
||||||
|
none
|
||||||
|
__depth_texture_2d_array
|
||||||
|
})",
|
||||||
|
R"(
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{textureSampleCompareLevel}
|
||||||
|
(
|
||||||
|
Identifier[not set]{x_20}
|
||||||
|
Identifier[not set]{x_10}
|
||||||
|
MemberAccessor[not set]{
|
||||||
|
Identifier[not set]{coords123}
|
||||||
|
Identifier[not set]{xy}
|
||||||
|
}
|
||||||
|
TypeConstructor[not set]{
|
||||||
|
__i32
|
||||||
|
MemberAccessor[not set]{
|
||||||
|
Identifier[not set]{coords123}
|
||||||
|
Identifier[not set]{z}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ScalarConstructor[not set]{0.200000}
|
||||||
|
)
|
||||||
|
})"},
|
||||||
|
// 2D, ConstOffset
|
||||||
|
ImageAccessCase{"%float 2D 1 0 0 1 Unknown",
|
||||||
|
"%result = OpImageSampleDrefExplicitLod %float "
|
||||||
|
"%sampled_image %coords12 %depth Lod|ConstOffset "
|
||||||
|
"%float_0 %offsets2d",
|
||||||
|
R"(
|
||||||
|
Variable{
|
||||||
|
Decorations{
|
||||||
|
GroupDecoration{0}
|
||||||
|
BindingDecoration{0}
|
||||||
|
}
|
||||||
|
x_10
|
||||||
|
none
|
||||||
|
__sampler_comparison
|
||||||
|
}
|
||||||
|
Variable{
|
||||||
|
Decorations{
|
||||||
|
GroupDecoration{2}
|
||||||
|
BindingDecoration{1}
|
||||||
|
}
|
||||||
|
x_20
|
||||||
|
none
|
||||||
|
__depth_texture_2d
|
||||||
|
})",
|
||||||
|
R"(
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{textureSampleCompareLevel}
|
||||||
|
(
|
||||||
|
Identifier[not set]{x_20}
|
||||||
|
Identifier[not set]{x_10}
|
||||||
|
Identifier[not set]{coords12}
|
||||||
|
ScalarConstructor[not set]{0.200000}
|
||||||
|
TypeConstructor[not set]{
|
||||||
|
__vec_2__i32
|
||||||
|
ScalarConstructor[not set]{3}
|
||||||
|
ScalarConstructor[not set]{4}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})"},
|
||||||
|
// 2D array, ConstOffset
|
||||||
|
ImageAccessCase{"%float 2D 1 1 0 1 Unknown",
|
||||||
|
"%result = OpImageSampleDrefExplicitLod %float "
|
||||||
|
"%sampled_image %coords123 %depth Lod|ConstOffset "
|
||||||
|
"%float_0 %offsets2d",
|
||||||
|
R"(
|
||||||
|
Variable{
|
||||||
|
Decorations{
|
||||||
|
GroupDecoration{0}
|
||||||
|
BindingDecoration{0}
|
||||||
|
}
|
||||||
|
x_10
|
||||||
|
none
|
||||||
|
__sampler_comparison
|
||||||
|
}
|
||||||
|
Variable{
|
||||||
|
Decorations{
|
||||||
|
GroupDecoration{2}
|
||||||
|
BindingDecoration{1}
|
||||||
|
}
|
||||||
|
x_20
|
||||||
|
none
|
||||||
|
__depth_texture_2d_array
|
||||||
|
})",
|
||||||
|
R"(
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{textureSampleCompareLevel}
|
||||||
|
(
|
||||||
|
Identifier[not set]{x_20}
|
||||||
|
Identifier[not set]{x_10}
|
||||||
|
MemberAccessor[not set]{
|
||||||
|
Identifier[not set]{coords123}
|
||||||
|
Identifier[not set]{xy}
|
||||||
|
}
|
||||||
|
TypeConstructor[not set]{
|
||||||
|
__i32
|
||||||
|
MemberAccessor[not set]{
|
||||||
|
Identifier[not set]{coords123}
|
||||||
|
Identifier[not set]{z}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ScalarConstructor[not set]{0.200000}
|
||||||
|
TypeConstructor[not set]{
|
||||||
|
__vec_2__i32
|
||||||
|
ScalarConstructor[not set]{3}
|
||||||
|
ScalarConstructor[not set]{4}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})"},
|
||||||
|
// Cube
|
||||||
|
ImageAccessCase{"%float Cube 1 0 0 1 Unknown",
|
||||||
|
"%result = OpImageSampleDrefExplicitLod "
|
||||||
|
"%float %sampled_image %coords123 %depth Lod %float_0",
|
||||||
|
R"(
|
||||||
|
Variable{
|
||||||
|
Decorations{
|
||||||
|
GroupDecoration{0}
|
||||||
|
BindingDecoration{0}
|
||||||
|
}
|
||||||
|
x_10
|
||||||
|
none
|
||||||
|
__sampler_comparison
|
||||||
|
}
|
||||||
|
Variable{
|
||||||
|
Decorations{
|
||||||
|
GroupDecoration{2}
|
||||||
|
BindingDecoration{1}
|
||||||
|
}
|
||||||
|
x_20
|
||||||
|
none
|
||||||
|
__depth_texture_cube
|
||||||
|
})",
|
||||||
|
R"(
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{textureSampleCompareLevel}
|
||||||
|
(
|
||||||
|
Identifier[not set]{x_20}
|
||||||
|
Identifier[not set]{x_10}
|
||||||
|
Identifier[not set]{coords123}
|
||||||
|
ScalarConstructor[not set]{0.200000}
|
||||||
|
)
|
||||||
|
})"},
|
||||||
|
// Cube array
|
||||||
|
ImageAccessCase{"%float Cube 1 1 0 1 Unknown",
|
||||||
|
"%result = OpImageSampleDrefExplicitLod "
|
||||||
|
"%float %sampled_image %coords1234 %depth Lod %float_0",
|
||||||
|
R"(
|
||||||
|
Variable{
|
||||||
|
Decorations{
|
||||||
|
GroupDecoration{0}
|
||||||
|
BindingDecoration{0}
|
||||||
|
}
|
||||||
|
x_10
|
||||||
|
none
|
||||||
|
__sampler_comparison
|
||||||
|
}
|
||||||
|
Variable{
|
||||||
|
Decorations{
|
||||||
|
GroupDecoration{2}
|
||||||
|
BindingDecoration{1}
|
||||||
|
}
|
||||||
|
x_20
|
||||||
|
none
|
||||||
|
__depth_texture_cube_array
|
||||||
|
})",
|
||||||
|
R"(
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{textureSampleCompareLevel}
|
||||||
|
(
|
||||||
|
Identifier[not set]{x_20}
|
||||||
|
Identifier[not set]{x_10}
|
||||||
|
MemberAccessor[not set]{
|
||||||
|
Identifier[not set]{coords1234}
|
||||||
|
Identifier[not set]{xyz}
|
||||||
|
}
|
||||||
|
TypeConstructor[not set]{
|
||||||
|
__i32
|
||||||
|
MemberAccessor[not set]{
|
||||||
|
Identifier[not set]{coords1234}
|
||||||
|
Identifier[not set]{w}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ScalarConstructor[not set]{0.200000}
|
||||||
|
)
|
||||||
|
})"}));
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
ImageSampleExplicitLod_UsingLod,
|
ImageSampleExplicitLod_UsingLod,
|
||||||
SpvParserHandleTest_SampledImageAccessTest,
|
SpvParserHandleTest_SampledImageAccessTest,
|
||||||
|
@ -3156,7 +3402,7 @@ TEST_F(SpvParserHandleTest, ImageWrite_TooFewSrcTexelComponents_1_vs_4) {
|
||||||
EXPECT_FALSE(p->BuildAndParseInternalModule());
|
EXPECT_FALSE(p->BuildAndParseInternalModule());
|
||||||
EXPECT_THAT(p->error(),
|
EXPECT_THAT(p->error(),
|
||||||
Eq("texel has too few components for storage texture: 1 provided "
|
Eq("texel has too few components for storage texture: 1 provided "
|
||||||
"but 4 required, in: OpImageWrite %53 %3 %2"))
|
"but 4 required, in: OpImageWrite %54 %3 %2"))
|
||||||
<< p->error();
|
<< p->error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5365,7 +5611,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
{"Identifier[not set]{vf12}\n"}},
|
{"Identifier[not set]{vf12}\n"}},
|
||||||
{"%float 2D 1 0 0 1 Unknown",
|
{"%float 2D 1 0 0 1 Unknown",
|
||||||
"%result = OpImageSampleDrefExplicitLod %float %sampled_image %vf12 "
|
"%result = OpImageSampleDrefExplicitLod %float %sampled_image %vf12 "
|
||||||
"%depth Lod %f1",
|
"%depth Lod %float_0",
|
||||||
"",
|
"",
|
||||||
{"Identifier[not set]{vf12}\n"}},
|
{"Identifier[not set]{vf12}\n"}},
|
||||||
}));
|
}));
|
||||||
|
@ -5434,7 +5680,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
)"}},
|
)"}},
|
||||||
{"%float 2D 1 1 0 1 Unknown",
|
{"%float 2D 1 1 0 1 Unknown",
|
||||||
"%result = OpImageSampleDrefExplicitLod %float %sampled_image "
|
"%result = OpImageSampleDrefExplicitLod %float %sampled_image "
|
||||||
"%vf123 %depth Lod %f1",
|
"%vf123 %depth Lod %float_0",
|
||||||
"",
|
"",
|
||||||
{
|
{
|
||||||
R"(MemberAccessor[not set]{
|
R"(MemberAccessor[not set]{
|
||||||
|
@ -5668,7 +5914,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
{"%float 1D 0 0 0 1 Unknown",
|
{"%float 1D 0 0 0 1 Unknown",
|
||||||
"%50 = OpCopyObject %float %float_1",
|
"%50 = OpCopyObject %float %float_1",
|
||||||
"internal error: couldn't find image for "
|
"internal error: couldn't find image for "
|
||||||
"%50 = OpCopyObject %18 %44",
|
"%50 = OpCopyObject %18 %45",
|
||||||
{}},
|
{}},
|
||||||
{"%float 1D 0 0 0 1 Unknown",
|
{"%float 1D 0 0 0 1 Unknown",
|
||||||
"OpStore %float_var %float_1",
|
"OpStore %float_var %float_1",
|
||||||
|
@ -5687,29 +5933,29 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"%result = OpImageSampleImplicitLod "
|
"%result = OpImageSampleImplicitLod "
|
||||||
// bad type for coordinate: not a number
|
// bad type for coordinate: not a number
|
||||||
"%v4float %sampled_image %float_var",
|
"%v4float %sampled_image %float_var",
|
||||||
"bad or unsupported coordinate type for image access: %72 = "
|
"bad or unsupported coordinate type for image access: %73 = "
|
||||||
"OpImageSampleImplicitLod %42 %71 %1",
|
"OpImageSampleImplicitLod %42 %72 %1",
|
||||||
{}},
|
{}},
|
||||||
{"%float 2D 0 0 0 1 Unknown", // 2D
|
{"%float 2D 0 0 0 1 Unknown", // 2D
|
||||||
"%result = OpImageSampleImplicitLod "
|
"%result = OpImageSampleImplicitLod "
|
||||||
// 1 component, but need 2
|
// 1 component, but need 2
|
||||||
"%v4float %sampled_image %f1",
|
"%v4float %sampled_image %f1",
|
||||||
"image access required 2 coordinate components, but only 1 provided, "
|
"image access required 2 coordinate components, but only 1 provided, "
|
||||||
"in: %72 = OpImageSampleImplicitLod %42 %71 %12",
|
"in: %73 = OpImageSampleImplicitLod %42 %72 %12",
|
||||||
{}},
|
{}},
|
||||||
{"%float 2D 0 1 0 1 Unknown", // 2DArray
|
{"%float 2D 0 1 0 1 Unknown", // 2DArray
|
||||||
"%result = OpImageSampleImplicitLod "
|
"%result = OpImageSampleImplicitLod "
|
||||||
// 2 component, but need 3
|
// 2 component, but need 3
|
||||||
"%v4float %sampled_image %vf12",
|
"%v4float %sampled_image %vf12",
|
||||||
"image access required 3 coordinate components, but only 2 provided, "
|
"image access required 3 coordinate components, but only 2 provided, "
|
||||||
"in: %72 = OpImageSampleImplicitLod %42 %71 %13",
|
"in: %73 = OpImageSampleImplicitLod %42 %72 %13",
|
||||||
{}},
|
{}},
|
||||||
{"%float 3D 0 0 0 1 Unknown", // 3D
|
{"%float 3D 0 0 0 1 Unknown", // 3D
|
||||||
"%result = OpImageSampleImplicitLod "
|
"%result = OpImageSampleImplicitLod "
|
||||||
// 2 components, but need 3
|
// 2 components, but need 3
|
||||||
"%v4float %sampled_image %vf12",
|
"%v4float %sampled_image %vf12",
|
||||||
"image access required 3 coordinate components, but only 2 provided, "
|
"image access required 3 coordinate components, but only 2 provided, "
|
||||||
"in: %72 = OpImageSampleImplicitLod %42 %71 %13",
|
"in: %73 = OpImageSampleImplicitLod %42 %72 %13",
|
||||||
{}},
|
{}},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -5751,12 +5997,12 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
// ImageSampleDrefExplicitLod
|
// ImageSampleDrefExplicitLod
|
||||||
{"%uint 2D 0 0 0 1 Unknown",
|
{"%uint 2D 0 0 0 1 Unknown",
|
||||||
"%result = OpImageSampleDrefExplicitLod %uint %sampled_image %vf12 "
|
"%result = OpImageSampleDrefExplicitLod %uint %sampled_image %vf12 "
|
||||||
"%f1 Lod %f1",
|
"%f1 Lod %float_0",
|
||||||
"sampled image must have float component type",
|
"sampled image must have float component type",
|
||||||
{}},
|
{}},
|
||||||
{"%int 2D 0 0 0 1 Unknown",
|
{"%int 2D 0 0 0 1 Unknown",
|
||||||
"%result = OpImageSampleDrefExplicitLod %int %sampled_image %vf12 "
|
"%result = OpImageSampleDrefExplicitLod %int %sampled_image %vf12 "
|
||||||
"%f1 Lod %f1",
|
"%f1 Lod %float_0",
|
||||||
"sampled image must have float component type",
|
"sampled image must have float component type",
|
||||||
{}}}));
|
{}}}));
|
||||||
|
|
||||||
|
@ -5845,6 +6091,43 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
"gradient: ",
|
"gradient: ",
|
||||||
{}}}));
|
{}}}));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
ImageSampleDrefExplicitLod_CheckForLod0,
|
||||||
|
// Metal requires comparison sampling with explicit Level-of-detail to use
|
||||||
|
// Lod 0. The SPIR-V reader requires the operand to be parsed as a constant
|
||||||
|
// 0 value. SPIR-V validation requires the Lod parameter to be a floating
|
||||||
|
// point value for non-fetch operations. So only test float values.
|
||||||
|
SpvParserHandleTest_ImageCoordsTest,
|
||||||
|
::testing::ValuesIn(std::vector<ImageCoordsCase>{
|
||||||
|
// float 0.0 works
|
||||||
|
{"%float 2D 1 0 0 1 Unknown",
|
||||||
|
"%result = OpImageSampleDrefExplicitLod %float %sampled_image %vf1234 "
|
||||||
|
"%depth Lod %float_0",
|
||||||
|
"",
|
||||||
|
{R"(MemberAccessor[not set]{
|
||||||
|
Identifier[not set]{vf1234}
|
||||||
|
Identifier[not set]{xy}
|
||||||
|
}
|
||||||
|
)"}},
|
||||||
|
// float null works
|
||||||
|
{"%float 2D 1 0 0 1 Unknown",
|
||||||
|
"%result = OpImageSampleDrefExplicitLod %float %sampled_image %vf1234 "
|
||||||
|
"%depth Lod %float_0",
|
||||||
|
"",
|
||||||
|
{R"(MemberAccessor[not set]{
|
||||||
|
Identifier[not set]{vf1234}
|
||||||
|
Identifier[not set]{xy}
|
||||||
|
}
|
||||||
|
)"}},
|
||||||
|
// float 1.0 fails.
|
||||||
|
{"%float 2D 1 0 0 1 Unknown",
|
||||||
|
"%result = OpImageSampleDrefExplicitLod %float %sampled_image %vf1234 "
|
||||||
|
"%depth Lod %float_1",
|
||||||
|
"WGSL comparison sampling without derivatives requires "
|
||||||
|
"level-of-detail "
|
||||||
|
"0.0",
|
||||||
|
{}}}));
|
||||||
|
|
||||||
TEST_F(SpvParserHandleTest, CombinedImageSampler_IsError) {
|
TEST_F(SpvParserHandleTest, CombinedImageSampler_IsError) {
|
||||||
const auto assembly = Preamble() + R"(
|
const auto assembly = Preamble() + R"(
|
||||||
OpEntryPoint Fragment %100 "main"
|
OpEntryPoint Fragment %100 "main"
|
||||||
|
|
Loading…
Reference in New Issue