mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-23 20:20:06 +00:00
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:
parent
2a2bdbd5d7
commit
7d65bce0bb
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user