aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorseppala2 <atte.seppala@gmail.com>2021-02-19 17:59:14 +0200
committerGitHub <noreply@github.com>2021-02-19 10:59:14 -0500
commitef3290bbea35935ba8fd623970511ed9f045bbd7 (patch)
treecdf8cf856b8b694d560e88ba23590539c76c6e4f
parent1b35745ad1c9a988bc427b976a9a2fe7afd4dada (diff)
downloadspirv-tools-ef3290bbea35935ba8fd623970511ed9f045bbd7.tar.gz
spirv-opt: Don't call GenerateCopy for mismatched image types (#4126)
Avoid an assertion that will cause some HLSL shader to fail. They will be legalized by later passes that will do copy propagation.
-rw-r--r--source/opt/fix_storage_class.cpp10
-rw-r--r--test/opt/fix_storage_class_test.cpp42
2 files changed, 52 insertions, 0 deletions
diff --git a/source/opt/fix_storage_class.cpp b/source/opt/fix_storage_class.cpp
index 03da0d0d..04eb1326 100644
--- a/source/opt/fix_storage_class.cpp
+++ b/source/opt/fix_storage_class.cpp
@@ -222,6 +222,16 @@ bool FixStorageClass::PropagateType(Instruction* inst, uint32_t type_id,
uint32_t pointee_type_id = GetPointeeTypeId(ptr_inst);
if (obj_type_id != pointee_type_id) {
+ if (context()->get_type_mgr()->GetType(obj_type_id)->AsImage() &&
+ context()->get_type_mgr()->GetType(pointee_type_id)->AsImage()) {
+ // When storing an image, allow the type mismatch
+ // and let the later legalization passes eliminate the OpStore.
+ // This is to support assigning an image to a variable,
+ // where the assigned image does not have a pre-defined
+ // image format.
+ return false;
+ }
+
uint32_t copy_id = GenerateCopy(obj_inst, pointee_type_id, inst);
inst->SetInOperand(1, {copy_id});
context()->UpdateDefUse(inst);
diff --git a/test/opt/fix_storage_class_test.cpp b/test/opt/fix_storage_class_test.cpp
index 4c8504ae..1c0101a0 100644
--- a/test/opt/fix_storage_class_test.cpp
+++ b/test/opt/fix_storage_class_test.cpp
@@ -528,6 +528,48 @@ TEST_F(FixStorageClassTest, FixLinkedAccessChain2) {
SinglePassRunAndMatch<FixStorageClass>(text, false);
}
+TEST_F(FixStorageClassTest, AllowImageFormatMismatch) {
+ const std::string text = R"(OpCapability Shader
+OpCapability SampledBuffer
+OpCapability ImageBuffer
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpSource HLSL 600
+OpName %type_buffer_image "type.buffer.image"
+OpName %Buf "Buf"
+OpName %main "main"
+OpName %src_main "src.main"
+OpName %bb_entry "bb.entry"
+OpName %type_buffer_image_0 "type.buffer.image"
+OpName %b "b"
+OpDecorate %Buf DescriptorSet 0
+OpDecorate %Buf Binding 0
+%float = OpTypeFloat 32
+%type_buffer_image = OpTypeImage %float Buffer 2 0 0 2 Rgba16f
+%_ptr_UniformConstant_type_buffer_image = OpTypePointer UniformConstant %type_buffer_image
+%void = OpTypeVoid
+%11 = OpTypeFunction %void
+%type_buffer_image_0 = OpTypeImage %float Buffer 2 0 0 2 Rgba32f
+%_ptr_Function_type_buffer_image_0 = OpTypePointer Function %type_buffer_image_0
+%Buf = OpVariable %_ptr_UniformConstant_type_buffer_image UniformConstant
+%main = OpFunction %void None %11
+%13 = OpLabel
+%14 = OpFunctionCall %void %src_main
+OpReturn
+OpFunctionEnd
+%src_main = OpFunction %void None %11
+%bb_entry = OpLabel
+%b = OpVariable %_ptr_Function_type_buffer_image_0 Function
+%15 = OpLoad %type_buffer_image %Buf
+OpStore %b %15
+OpReturn
+OpFunctionEnd
+)";
+
+ SinglePassRunAndCheck<FixStorageClass>(text, text, false, false);
+}
+
using FixTypeTest = PassTest<::testing::Test>;
TEST_F(FixTypeTest, FixAccessChain) {