Sampled images as read-only storage (#3295)

There are some cases where a variable that is declared as a sampled
image could be read only.  That is when the image type has sampled == 1.

Fixes #3288
This commit is contained in:
Steven Perron 2020-04-14 12:58:05 -04:00 committed by GitHub
parent 2a2bdbd5d7
commit 7d65bce0bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 63 additions and 2 deletions

View File

@ -182,10 +182,27 @@ void Instruction::ReplaceOperands(const OperandList& new_operands) {
bool Instruction::IsReadOnlyLoad() const {
if (IsLoad()) {
Instruction* address_def = GetBaseAddress();
if (!address_def || address_def->opcode() != SpvOpVariable) {
if (!address_def) {
return false;
}
return address_def->IsReadOnlyVariable();
if (address_def->opcode() == SpvOpVariable) {
if (address_def->IsReadOnlyVariable()) {
return true;
}
}
if (address_def->opcode() == SpvOpLoad) {
const analysis::Type* address_type =
context()->get_type_mgr()->GetType(address_def->type_id());
if (address_type->AsSampledImage() != nullptr) {
const auto* image_type =
address_type->AsSampledImage()->image_type()->AsImage();
if (image_type->sampled() == 1) {
return true;
}
}
}
}
return false;
}

View File

@ -684,6 +684,50 @@ TEST_F(ValueTableTest, EmptyPhiTest) {
vtable.GetValueNumber(inst);
}
TEST_F(ValueTableTest, RedundantSampledImageLoad) {
const std::string text = R"(
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %gl_FragColor
OpExecutionMode %main OriginLowerLeft
OpSource GLSL 330
OpName %main "main"
OpName %tex0 "tex0"
OpName %gl_FragColor "gl_FragColor"
OpDecorate %tex0 Location 0
OpDecorate %tex0 DescriptorSet 0
OpDecorate %tex0 Binding 0
OpDecorate %gl_FragColor Location 0
%void = OpTypeVoid
%6 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%9 = OpTypeImage %float 2D 0 0 0 1 Unknown
%10 = OpTypeSampledImage %9
%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
%tex0 = OpVariable %_ptr_UniformConstant_10 UniformConstant
%_ptr_Output_v4float = OpTypePointer Output %v4float
%13 = OpConstantNull %v4float
%gl_FragColor = OpVariable %_ptr_Output_v4float Output
%14 = OpUndef %v4float
%main = OpFunction %void None %6
%15 = OpLabel
%16 = OpLoad %10 %tex0
%17 = OpImageSampleProjImplicitLod %v4float %16 %13
%18 = OpImageSampleProjImplicitLod %v4float %16 %13
%19 = OpFAdd %v4float %18 %17
OpStore %gl_FragColor %19
OpReturn
OpFunctionEnd
)";
auto context = BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
ValueNumberTable vtable(context.get());
Instruction* load1 = context->get_def_use_mgr()->GetDef(17);
Instruction* load2 = context->get_def_use_mgr()->GetDef(18);
EXPECT_EQ(vtable.GetValueNumber(load1), vtable.GetValueNumber(load2));
}
} // namespace
} // namespace opt
} // namespace spvtools