mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-10-18 11:10:05 +00:00
spirv-fuzz: Handle image storage class in donation (#3290)
Demotes the image storage class to Private during donation. Also fixes an issue where instructions that depended on non-donated global values would not be handled properly.
This commit is contained in:
parent
f82d47003e
commit
2f180468a7
@ -124,6 +124,7 @@ SpvStorageClass FuzzerPassDonateModules::AdaptStorageClass(
|
||||
case SpvStorageClassUniform:
|
||||
case SpvStorageClassUniformConstant:
|
||||
case SpvStorageClassPushConstant:
|
||||
case SpvStorageClassImage:
|
||||
// We change these to Private
|
||||
return SpvStorageClassPrivate;
|
||||
default:
|
||||
@ -721,11 +722,12 @@ bool FuzzerPassDonateModules::CanDonateInstruction(
|
||||
// We do not have a mapped result id for this id operand. That either
|
||||
// means that it is a forward reference (which is OK), that we skipped
|
||||
// the instruction that generated it (which is not OK), or that it is
|
||||
// the id of a function that we did not donate (which is not OK). We
|
||||
// check for the latter two cases.
|
||||
// the id of a function or global value that we did not donate (which
|
||||
// is not OK). We check for the latter two cases.
|
||||
if (skipped_instructions.count(*in_id) ||
|
||||
donor_ir_context->get_def_use_mgr()->GetDef(*in_id)->opcode() ==
|
||||
SpvOpFunction) {
|
||||
// A function or global value does not have an associated basic
|
||||
// block.
|
||||
!donor_ir_context->get_instr_block(*in_id)) {
|
||||
result = false;
|
||||
return false;
|
||||
}
|
||||
|
@ -1058,6 +1058,85 @@ TEST(FuzzerPassDonateModulesTest, DonateCodeThatUsesImageFunctionParameter) {
|
||||
ASSERT_TRUE(IsValid(env, recipient_context.get()));
|
||||
}
|
||||
|
||||
TEST(FuzzerPassDonateModulesTest, DonateShaderWithImageStorageClass) {
|
||||
std::string recipient_shader = R"(
|
||||
OpCapability Shader
|
||||
OpCapability ImageQuery
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %4 "main"
|
||||
OpExecutionMode %4 OriginUpperLeft
|
||||
OpSource ESSL 320
|
||||
OpSourceExtension "GL_EXT_samplerless_texture_functions"
|
||||
%2 = OpTypeVoid
|
||||
%3 = OpTypeFunction %2
|
||||
%4 = OpFunction %2 None %3
|
||||
%5 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
std::string donor_shader = R"(
|
||||
OpCapability Shader
|
||||
OpCapability SampledBuffer
|
||||
OpCapability ImageBuffer
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %2 "MainPSPacked"
|
||||
OpExecutionMode %2 OriginUpperLeft
|
||||
OpDecorate %18 DescriptorSet 0
|
||||
OpDecorate %18 Binding 128
|
||||
%49 = OpTypeInt 32 0
|
||||
%50 = OpTypeFloat 32
|
||||
%58 = OpConstant %50 1
|
||||
%66 = OpConstant %49 0
|
||||
%87 = OpTypeVector %50 2
|
||||
%88 = OpConstantComposite %87 %58 %58
|
||||
%17 = OpTypeImage %49 2D 2 0 0 2 R32ui
|
||||
%118 = OpTypePointer UniformConstant %17
|
||||
%123 = OpTypeVector %49 2
|
||||
%132 = OpTypeVoid
|
||||
%133 = OpTypeFunction %132
|
||||
%142 = OpTypePointer Image %49
|
||||
%18 = OpVariable %118 UniformConstant
|
||||
%2 = OpFunction %132 None %133
|
||||
%153 = OpLabel
|
||||
%495 = OpConvertFToU %123 %88
|
||||
%501 = OpImageTexelPointer %142 %18 %495 %66
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
const auto env = SPV_ENV_UNIVERSAL_1_3;
|
||||
const auto consumer = nullptr;
|
||||
const auto recipient_context =
|
||||
BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption);
|
||||
ASSERT_TRUE(IsValid(env, recipient_context.get()));
|
||||
|
||||
const auto donor_context =
|
||||
BuildModule(env, consumer, donor_shader, kFuzzAssembleOption);
|
||||
ASSERT_TRUE(IsValid(env, donor_context.get()));
|
||||
|
||||
FactManager fact_manager;
|
||||
spvtools::ValidatorOptions validator_options;
|
||||
TransformationContext transformation_context(&fact_manager,
|
||||
validator_options);
|
||||
|
||||
PseudoRandomGenerator prng(0);
|
||||
FuzzerContext fuzzer_context(&prng, 100);
|
||||
protobufs::TransformationSequence transformation_sequence;
|
||||
|
||||
FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
|
||||
&transformation_context, &fuzzer_context,
|
||||
&transformation_sequence, {});
|
||||
|
||||
fuzzer_pass.DonateSingleModule(donor_context.get(), true);
|
||||
|
||||
// We just check that the result is valid. Checking to what it should be
|
||||
// exactly equal to would be very fragile.
|
||||
ASSERT_TRUE(IsValid(env, recipient_context.get()));
|
||||
}
|
||||
|
||||
TEST(FuzzerPassDonateModulesTest, DonateComputeShaderWithRuntimeArray) {
|
||||
std::string recipient_shader = R"(
|
||||
OpCapability Shader
|
||||
|
Loading…
Reference in New Issue
Block a user