diff --git a/source/fuzz/fact_manager.cpp b/source/fuzz/fact_manager.cpp index 407881be5..9cb6896a4 100644 --- a/source/fuzz/fact_manager.cpp +++ b/source/fuzz/fact_manager.cpp @@ -201,20 +201,21 @@ bool FactManager::ConstantUniformFacts::FloatingPointValueIsSuitable( bool FactManager::ConstantUniformFacts::AddFact( const protobufs::FactConstantUniform& fact, opt::IRContext* context) { - auto should_be_uniform_variable = context->get_def_use_mgr()->GetDef( - fact.uniform_buffer_element_descriptor().uniform_variable_id()); - if (!should_be_uniform_variable) { - return false; - } - if (SpvOpVariable != should_be_uniform_variable->opcode()) { - return false; - } - if (SpvStorageClassUniform != - should_be_uniform_variable->GetSingleWordInOperand(0)) { + // Try to find a unique instruction that declares a variable such that the + // variable is decorated with the descriptor set and binding associated with + // the constant uniform fact. + opt::Instruction* uniform_variable = FindUniformVariable( + fact.uniform_buffer_element_descriptor(), context, true); + + if (!uniform_variable) { return false; } + + assert(SpvOpVariable == uniform_variable->opcode()); + assert(SpvStorageClassUniform == uniform_variable->GetSingleWordInOperand(0)); + auto should_be_uniform_pointer_type = - context->get_type_mgr()->GetType(should_be_uniform_variable->type_id()); + context->get_type_mgr()->GetType(uniform_variable->type_id()); if (!should_be_uniform_pointer_type->AsPointer()) { return false; } @@ -223,7 +224,7 @@ bool FactManager::ConstantUniformFacts::AddFact( return false; } auto should_be_uniform_pointer_instruction = - context->get_def_use_mgr()->GetDef(should_be_uniform_variable->type_id()); + context->get_def_use_mgr()->GetDef(uniform_variable->type_id()); auto element_type = should_be_uniform_pointer_instruction->GetSingleWordInOperand(1); diff --git a/source/fuzz/protobufs/spvtoolsfuzz.proto b/source/fuzz/protobufs/spvtoolsfuzz.proto index 941a2ca62..aecd4c7a9 100644 --- a/source/fuzz/protobufs/spvtoolsfuzz.proto +++ b/source/fuzz/protobufs/spvtoolsfuzz.proto @@ -64,8 +64,9 @@ message UniformBufferElementDescriptor { // is contained, and (b) a series of indices that need to be followed to get // to the element (via fields and array/vector indices). // - // Example: suppose %42 is the id of a uniform variable, and that the uniform - // variable has the following type (using GLSL-like syntax): + // Example: suppose there is a uniform variable with descriptor set 7 and + // binding 9, and that the uniform variable has the following type (using + // GLSL-like syntax): // // struct S { // float f; @@ -74,16 +75,17 @@ message UniformBufferElementDescriptor { // }; // // Then: - // - 42[0] describes the 'f' field. - // - 42[1,1] describes the y component of the 'g' field. - // - 42[2,7,3] describes the w component of element 7 of the 'h' field + // - (7, 9, [0]) describes the 'f' field. + // - (7, 9, [1,1]) describes the y component of the 'g' field. + // - (7, 9, [2,7,3]) describes the w component of element 7 of the 'h' field - // The result id of a uniform variable. - uint32 uniform_variable_id = 1; + // The descriptor set and binding associated with a uniform variable. + uint32 descriptor_set = 1; + uint32 binding = 2; // An ordered sequence of indices through composite structures in the // uniform buffer. - repeated uint32 index = 2; + repeated uint32 index = 3; } diff --git a/source/fuzz/transformation_replace_constant_with_uniform.cpp b/source/fuzz/transformation_replace_constant_with_uniform.cpp index fce458c6f..cc6e1374a 100644 --- a/source/fuzz/transformation_replace_constant_with_uniform.cpp +++ b/source/fuzz/transformation_replace_constant_with_uniform.cpp @@ -15,6 +15,7 @@ #include "source/fuzz/transformation_replace_constant_with_uniform.h" #include "source/fuzz/fuzzer_util.h" +#include "source/fuzz/uniform_buffer_element_descriptor.h" namespace spvtools { namespace fuzz { @@ -28,10 +29,12 @@ std::unique_ptr MakeAccessChainInstruction( // The input operands for the access chain. opt::Instruction::OperandList operands_for_access_chain; + opt::Instruction* uniform_variable = + FindUniformVariable(message.uniform_descriptor(), context, false); + // The first input operand is the id of the uniform variable. operands_for_access_chain.push_back( - {SPV_OPERAND_TYPE_ID, - {message.uniform_descriptor().uniform_variable_id()}}); + {SPV_OPERAND_TYPE_ID, {uniform_variable->result_id()}}); // The other input operands are the ids of the constants used to index into // the uniform. The uniform buffer descriptor specifies a series of literals; diff --git a/source/fuzz/uniform_buffer_element_descriptor.cpp b/source/fuzz/uniform_buffer_element_descriptor.cpp index cd840d3b6..8c758e421 100644 --- a/source/fuzz/uniform_buffer_element_descriptor.cpp +++ b/source/fuzz/uniform_buffer_element_descriptor.cpp @@ -14,13 +14,17 @@ #include "source/fuzz/uniform_buffer_element_descriptor.h" +#include + namespace spvtools { namespace fuzz { protobufs::UniformBufferElementDescriptor MakeUniformBufferElementDescriptor( - uint32_t uniform_variable_id, std::vector&& indices) { + uint32_t descriptor_set, uint32_t binding, + std::vector&& indices) { protobufs::UniformBufferElementDescriptor result; - result.set_uniform_variable_id(uniform_variable_id); + result.set_descriptor_set(descriptor_set); + result.set_binding(binding); for (auto index : indices) { result.add_index(index); } @@ -30,10 +34,85 @@ protobufs::UniformBufferElementDescriptor MakeUniformBufferElementDescriptor( bool UniformBufferElementDescriptorEquals::operator()( const protobufs::UniformBufferElementDescriptor* first, const protobufs::UniformBufferElementDescriptor* second) const { - return first->uniform_variable_id() == second->uniform_variable_id() && + return first->descriptor_set() == second->descriptor_set() && + first->binding() == second->binding() && + first->index().size() == second->index().size() && std::equal(first->index().begin(), first->index().end(), second->index().begin()); } +opt::Instruction* FindUniformVariable( + const protobufs::UniformBufferElementDescriptor& + uniform_buffer_element_descriptor, + opt::IRContext* context, bool check_unique) { + opt::Instruction* result = nullptr; + + for (auto& inst : context->types_values()) { + // Consider all global variables with uniform storage class. + if (inst.opcode() != SpvOpVariable) { + continue; + } + if (inst.GetSingleWordInOperand(0) != SpvStorageClassUniform) { + continue; + } + + // Determine whether the variable is decorated with a descriptor set + // matching that in |uniform_buffer_element|. + bool descriptor_set_matches = false; + context->get_decoration_mgr()->ForEachDecoration( + inst.result_id(), SpvDecorationDescriptorSet, + [&descriptor_set_matches, &uniform_buffer_element_descriptor]( + const opt::Instruction& decoration_inst) { + const uint32_t kDescriptorSetOperandIndex = 2; + if (decoration_inst.GetSingleWordInOperand( + kDescriptorSetOperandIndex) == + uniform_buffer_element_descriptor.descriptor_set()) { + descriptor_set_matches = true; + } + }); + if (!descriptor_set_matches) { + // Descriptor set does not match. + continue; + } + + // Determine whether the variable is decorated with a binding matching that + // in |uniform_buffer_element|. + bool binding_matches = false; + context->get_decoration_mgr()->ForEachDecoration( + inst.result_id(), SpvDecorationBinding, + [&binding_matches, &uniform_buffer_element_descriptor]( + const opt::Instruction& decoration_inst) { + const uint32_t kBindingOperandIndex = 2; + if (decoration_inst.GetSingleWordInOperand(kBindingOperandIndex) == + uniform_buffer_element_descriptor.binding()) { + binding_matches = true; + } + }); + if (!binding_matches) { + // Binding does not match. + continue; + } + + // This instruction is a uniform variable with the right descriptor set and + // binding. + if (!check_unique) { + // If we aren't checking uniqueness, return it. + return &inst; + } + + if (result) { + // More than one uniform variable is decorated with the given descriptor + // set and binding. This means the fact is ambiguous. + return nullptr; + } + result = &inst; + } + + // We get here either if no match was found, or if |check_unique| holds and + // exactly one match was found. + assert(result == nullptr || check_unique); + return result; +} + } // namespace fuzz } // namespace spvtools diff --git a/source/fuzz/uniform_buffer_element_descriptor.h b/source/fuzz/uniform_buffer_element_descriptor.h index b2e596231..23a16f0df 100644 --- a/source/fuzz/uniform_buffer_element_descriptor.h +++ b/source/fuzz/uniform_buffer_element_descriptor.h @@ -19,6 +19,8 @@ #include #include "source/fuzz/protobufs/spirvfuzz_protobufs.h" +#include "source/opt/instruction.h" +#include "source/opt/ir_context.h" namespace spvtools { namespace fuzz { @@ -26,7 +28,7 @@ namespace fuzz { // Factory method to create a uniform buffer element descriptor message from an // id and list of indices. protobufs::UniformBufferElementDescriptor MakeUniformBufferElementDescriptor( - uint32_t uniform_variable_id, std::vector&& indices); + uint32_t descriptor_set, uint32_t binding, std::vector&& indices); // Equality function for uniform buffer element descriptors. struct UniformBufferElementDescriptorEquals { @@ -35,6 +37,16 @@ struct UniformBufferElementDescriptorEquals { const protobufs::UniformBufferElementDescriptor* second) const; }; +// Returns a pointer to an OpVariable in |context| that is decorated with the +// descriptor set and binding associated with |uniform_buffer_element|. Returns +// nullptr if no such variable exists. If multiple such variables exist, a +// pointer to an arbitrary one of the associated instructions is returned if +// |check_unique| is false, and nullptr is returned if |check_unique| is true. +opt::Instruction* FindUniformVariable( + const protobufs::UniformBufferElementDescriptor& + uniform_buffer_element_descriptor, + opt::IRContext* context, bool check_unique); + } // namespace fuzz } // namespace spvtools diff --git a/test/fuzz/CMakeLists.txt b/test/fuzz/CMakeLists.txt index 454206c60..7b47b5530 100644 --- a/test/fuzz/CMakeLists.txt +++ b/test/fuzz/CMakeLists.txt @@ -31,7 +31,8 @@ if (${SPIRV_BUILD_FUZZER}) transformation_move_block_down_test.cpp transformation_replace_boolean_constant_with_constant_binary_test.cpp transformation_replace_constant_with_uniform_test.cpp - transformation_split_block_test.cpp) + transformation_split_block_test.cpp + uniform_buffer_element_descriptor_test.cpp) add_spvtools_unittest(TARGET fuzz SRCS ${SOURCES} diff --git a/test/fuzz/fact_manager_test.cpp b/test/fuzz/fact_manager_test.cpp index bf07f35a8..738f8c997 100644 --- a/test/fuzz/fact_manager_test.cpp +++ b/test/fuzz/fact_manager_test.cpp @@ -58,6 +58,44 @@ TEST(FactManagerTest, ConstantsAvailableViaUniforms) { OpExecutionMode %4 OriginUpperLeft OpSource GLSL 450 OpName %4 "main" + OpDecorate %100 DescriptorSet 0 + OpDecorate %100 Binding 0 + OpDecorate %200 DescriptorSet 0 + OpDecorate %200 Binding 1 + OpDecorate %300 DescriptorSet 0 + OpDecorate %300 Binding 2 + OpDecorate %400 DescriptorSet 0 + OpDecorate %400 Binding 3 + OpDecorate %500 DescriptorSet 0 + OpDecorate %500 Binding 4 + OpDecorate %600 DescriptorSet 0 + OpDecorate %600 Binding 5 + OpDecorate %700 DescriptorSet 0 + OpDecorate %700 Binding 6 + OpDecorate %800 DescriptorSet 1 + OpDecorate %800 Binding 0 + OpDecorate %900 DescriptorSet 1 + OpDecorate %900 Binding 1 + OpDecorate %1000 DescriptorSet 1 + OpDecorate %1000 Binding 2 + OpDecorate %1100 DescriptorSet 1 + OpDecorate %1100 Binding 3 + OpDecorate %1200 DescriptorSet 1 + OpDecorate %1200 Binding 4 + OpDecorate %1300 DescriptorSet 1 + OpDecorate %1300 Binding 5 + OpDecorate %1400 DescriptorSet 1 + OpDecorate %1400 Binding 6 + OpDecorate %1500 DescriptorSet 2 + OpDecorate %1500 Binding 0 + OpDecorate %1600 DescriptorSet 2 + OpDecorate %1600 Binding 1 + OpDecorate %1700 DescriptorSet 2 + OpDecorate %1700 Binding 2 + OpDecorate %1800 DescriptorSet 2 + OpDecorate %1800 Binding 3 + OpDecorate %1900 DescriptorSet 2 + OpDecorate %1900 Binding 4 %2 = OpTypeVoid %3 = OpTypeFunction %2 %10 = OpTypeInt 32 0 @@ -231,94 +269,98 @@ TEST(FactManagerTest, ConstantsAvailableViaUniforms) { type_uint32_id) .empty()); + // In the comments that follow we write v[...][...] to refer to uniform + // variable v indexed with some given indices, when in practice v is + // identified via a (descriptor set, binding) pair. + // 100[2][3] == int(1) ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {1}, - MakeUniformBufferElementDescriptor(100, {2, 3}))); + MakeUniformBufferElementDescriptor(0, 0, {2, 3}))); // 200[1][2][3] == int(1) ASSERT_TRUE( AddFactHelper(&fact_manager, context.get(), {1}, - MakeUniformBufferElementDescriptor(200, {1, 2, 3}))); + MakeUniformBufferElementDescriptor(0, 1, {1, 2, 3}))); // 300[1][0][2][3] == int(1) ASSERT_TRUE( AddFactHelper(&fact_manager, context.get(), {1}, - MakeUniformBufferElementDescriptor(300, {1, 0, 2, 3}))); + MakeUniformBufferElementDescriptor(0, 2, {1, 0, 2, 3}))); // 400[2][3] = int32_min ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {buffer_int32_min[0]}, - MakeUniformBufferElementDescriptor(400, {2, 3}))); + MakeUniformBufferElementDescriptor(0, 3, {2, 3}))); // 500[1][2][3] = int32_min ASSERT_TRUE( AddFactHelper(&fact_manager, context.get(), {buffer_int32_min[0]}, - MakeUniformBufferElementDescriptor(500, {1, 2, 3}))); + MakeUniformBufferElementDescriptor(0, 4, {1, 2, 3}))); // 600[1][2][3] = int64_max ASSERT_TRUE(AddFactHelper( &fact_manager, context.get(), {buffer_int64_max[0], buffer_int64_max[1]}, - MakeUniformBufferElementDescriptor(600, {1, 2, 3}))); + MakeUniformBufferElementDescriptor(0, 5, {1, 2, 3}))); // 700[1][1] = int64_max ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {buffer_int64_max[0], buffer_int64_max[1]}, - MakeUniformBufferElementDescriptor(700, {1, 1}))); + MakeUniformBufferElementDescriptor(0, 6, {1, 1}))); // 800[2][3] = uint(1) ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {1}, - MakeUniformBufferElementDescriptor(800, {2, 3}))); + MakeUniformBufferElementDescriptor(1, 0, {2, 3}))); // 900[1][2][3] = uint(1) ASSERT_TRUE( AddFactHelper(&fact_manager, context.get(), {1}, - MakeUniformBufferElementDescriptor(900, {1, 2, 3}))); + MakeUniformBufferElementDescriptor(1, 1, {1, 2, 3}))); // 1000[1][0][2][3] = uint(1) ASSERT_TRUE( AddFactHelper(&fact_manager, context.get(), {1}, - MakeUniformBufferElementDescriptor(1000, {1, 0, 2, 3}))); + MakeUniformBufferElementDescriptor(1, 2, {1, 0, 2, 3}))); // 1100[0] = uint64(1) ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {buffer_uint64_1[0], buffer_uint64_1[1]}, - MakeUniformBufferElementDescriptor(1100, {0}))); + MakeUniformBufferElementDescriptor(1, 3, {0}))); // 1200[0][0] = uint64_max ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {buffer_uint64_max[0], buffer_uint64_max[1]}, - MakeUniformBufferElementDescriptor(1200, {0, 0}))); + MakeUniformBufferElementDescriptor(1, 4, {0, 0}))); // 1300[1][0] = uint64_max ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {buffer_uint64_max[0], buffer_uint64_max[1]}, - MakeUniformBufferElementDescriptor(1300, {1, 0}))); + MakeUniformBufferElementDescriptor(1, 5, {1, 0}))); // 1400[6] = float(10.0) ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {buffer_float_10[0]}, - MakeUniformBufferElementDescriptor(1400, {6}))); + MakeUniformBufferElementDescriptor(1, 6, {6}))); // 1500[7] = float(10.0) ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {buffer_float_10[0]}, - MakeUniformBufferElementDescriptor(1500, {7}))); + MakeUniformBufferElementDescriptor(2, 0, {7}))); // 1600[9][9] = float(10.0) ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {buffer_float_10[0]}, - MakeUniformBufferElementDescriptor(1600, {9, 9}))); + MakeUniformBufferElementDescriptor(2, 1, {9, 9}))); // 1700[9][9][1] = double(10.0) ASSERT_TRUE(AddFactHelper( &fact_manager, context.get(), {buffer_double_10[0], buffer_double_10[1]}, - MakeUniformBufferElementDescriptor(1700, {9, 9, 1}))); + MakeUniformBufferElementDescriptor(2, 2, {9, 9, 1}))); // 1800[9][9][2] = double(10.0) ASSERT_TRUE(AddFactHelper( &fact_manager, context.get(), {buffer_double_10[0], buffer_double_10[1]}, - MakeUniformBufferElementDescriptor(1800, {9, 9, 2}))); + MakeUniformBufferElementDescriptor(2, 3, {9, 9, 2}))); // 1900[0][0][0][0][0] = double(20.0) ASSERT_TRUE(AddFactHelper( &fact_manager, context.get(), {buffer_double_20[0], buffer_double_20[1]}, - MakeUniformBufferElementDescriptor(1900, {0, 0, 0, 0, 0}))); + MakeUniformBufferElementDescriptor(2, 4, {0, 0, 0, 0, 0}))); opt::Instruction::OperandList operands = { {SPV_OPERAND_TYPE_LITERAL_INTEGER, {1}}}; @@ -429,12 +471,12 @@ TEST(FactManagerTest, ConstantsAvailableViaUniforms) { context.get(), double_constant_ids[0]); ASSERT_EQ(2, descriptors_for_double_10.size()); { - auto temp = MakeUniformBufferElementDescriptor(1700, {9, 9, 1}); + auto temp = MakeUniformBufferElementDescriptor(2, 2, {9, 9, 1}); ASSERT_TRUE(UniformBufferElementDescriptorEquals()( &temp, &descriptors_for_double_10[0])); } { - auto temp = MakeUniformBufferElementDescriptor(1800, {9, 9, 2}); + auto temp = MakeUniformBufferElementDescriptor(2, 3, {9, 9, 2}); ASSERT_TRUE(UniformBufferElementDescriptorEquals()( &temp, &descriptors_for_double_10[1])); } @@ -443,17 +485,17 @@ TEST(FactManagerTest, ConstantsAvailableViaUniforms) { context.get(), double_constant_ids[1]); ASSERT_EQ(1, descriptors_for_double_20.size()); { - auto temp = MakeUniformBufferElementDescriptor(1900, {0, 0, 0, 0, 0}); + auto temp = MakeUniformBufferElementDescriptor(2, 4, {0, 0, 0, 0, 0}); ASSERT_TRUE(UniformBufferElementDescriptorEquals()( &temp, &descriptors_for_double_20[0])); } auto constant_1_id = fact_manager.GetConstantFromUniformDescriptor( - context.get(), MakeUniformBufferElementDescriptor(1800, {9, 9, 2})); + context.get(), MakeUniformBufferElementDescriptor(2, 3, {9, 9, 2})); ASSERT_TRUE(constant_1_id); auto constant_2_id = fact_manager.GetConstantFromUniformDescriptor( - context.get(), MakeUniformBufferElementDescriptor(1900, {0, 0, 0, 0, 0})); + context.get(), MakeUniformBufferElementDescriptor(2, 4, {0, 0, 0, 0, 0})); ASSERT_TRUE(constant_2_id); ASSERT_EQ(double_constant_ids[0], constant_1_id); @@ -505,9 +547,9 @@ TEST(FactManagerTest, TwoConstantsWithSameValue) { FactManager fact_manager; auto uniform_buffer_element_descriptor = - MakeUniformBufferElementDescriptor(12, {0}); + MakeUniformBufferElementDescriptor(0, 0, {0}); - // 12[0] = int(1) + // (0, 0, [0]) = int(1) ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), {1}, uniform_buffer_element_descriptor)); auto constants = @@ -569,12 +611,11 @@ TEST(FactManagerTest, NonFiniteFactsAreNotValid) { ASSERT_TRUE(IsValid(env, context.get())); FactManager fact_manager; - auto uniform_buffer_element_descriptor_f = - MakeUniformBufferElementDescriptor(9, {0}); + MakeUniformBufferElementDescriptor(0, 0, {0}); auto uniform_buffer_element_descriptor_d = - MakeUniformBufferElementDescriptor(9, {1}); + MakeUniformBufferElementDescriptor(0, 0, {1}); if (std::numeric_limits::has_infinity) { // f == +inf @@ -626,6 +667,77 @@ TEST(FactManagerTest, NonFiniteFactsAreNotValid) { } } +TEST(FactManagerTest, AmbiguousFact) { + // This test came from the following GLSL: + // + // #version 310 es + // + // precision highp float; + // + // layout(set = 0, binding = 0) uniform buf { + // float f; + // }; + // + // layout(set = 0, binding = 0) uniform buf2 { + // float g; + // }; + // + // void main() { + // + // } + + std::string shader = R"( + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %4 "main" + OpExecutionMode %4 OriginUpperLeft + OpSource ESSL 310 + OpName %4 "main" + OpName %7 "buf" + OpMemberName %7 0 "f" + OpName %9 "" + OpName %10 "buf2" + OpMemberName %10 0 "g" + OpName %12 "" + OpMemberDecorate %7 0 Offset 0 + OpDecorate %7 Block + OpDecorate %9 DescriptorSet 0 + OpDecorate %9 Binding 0 + OpMemberDecorate %10 0 Offset 0 + OpDecorate %10 Block + OpDecorate %12 DescriptorSet 0 + OpDecorate %12 Binding 0 + %2 = OpTypeVoid + %3 = OpTypeFunction %2 + %6 = OpTypeFloat 32 + %7 = OpTypeStruct %6 + %8 = OpTypePointer Uniform %7 + %9 = OpVariable %8 Uniform + %10 = OpTypeStruct %6 + %11 = OpTypePointer Uniform %10 + %12 = OpVariable %11 Uniform + %4 = OpFunction %2 None %3 + %5 = OpLabel + OpReturn + OpFunctionEnd + )"; + + const auto env = SPV_ENV_UNIVERSAL_1_3; + const auto consumer = nullptr; + const auto context = BuildModule(env, consumer, shader, kFuzzAssembleOption); + ASSERT_TRUE(IsValid(env, context.get())); + + FactManager fact_manager; + auto uniform_buffer_element_descriptor = + MakeUniformBufferElementDescriptor(0, 0, {0}); + + // The fact cannot be added because it is ambiguous: there are two uniforms + // with descriptor set 0 and binding 0. + ASSERT_FALSE(AddFactHelper(&fact_manager, context.get(), {1}, + uniform_buffer_element_descriptor)); +} + } // namespace } // namespace fuzz } // namespace spvtools diff --git a/test/fuzz/fuzzer_pass_add_useful_constructs_test.cpp b/test/fuzz/fuzzer_pass_add_useful_constructs_test.cpp index 3cea32591..89f006e07 100644 --- a/test/fuzz/fuzzer_pass_add_useful_constructs_test.cpp +++ b/test/fuzz/fuzzer_pass_add_useful_constructs_test.cpp @@ -180,30 +180,30 @@ TEST(FuzzerPassAddUsefulConstructsTest, // buf.s.x == 200 ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 200, - MakeUniformBufferElementDescriptor(14, {0, 0}))); + MakeUniformBufferElementDescriptor(0, 0, {0, 0}))); // buf.s.y == 0.5 const float float_value = 0.5; uint32_t float_value_as_uint; memcpy(&float_value_as_uint, &float_value, sizeof(float_value)); ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_value_as_uint, - MakeUniformBufferElementDescriptor(14, {0, 1}))); + MakeUniformBufferElementDescriptor(0, 0, {0, 1}))); // buf.s.z == 300 ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 300, - MakeUniformBufferElementDescriptor(14, {0, 2}))); + MakeUniformBufferElementDescriptor(0, 0, {0, 2}))); // buf.s.w == 400 ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 400, - MakeUniformBufferElementDescriptor(14, {0, 3}))); + MakeUniformBufferElementDescriptor(0, 0, {0, 3}))); // buf.w[6] = 22 ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 22, - MakeUniformBufferElementDescriptor(14, {1, 6}))); + MakeUniformBufferElementDescriptor(0, 0, {1, 6}))); // buf.w[8] = 23 ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 23, - MakeUniformBufferElementDescriptor(14, {1, 8}))); + MakeUniformBufferElementDescriptor(0, 0, {1, 8}))); // Assert some things about the module that are not true prior to adding the // pass diff --git a/test/fuzz/fuzzer_replayer_test.cpp b/test/fuzz/fuzzer_replayer_test.cpp index bd753afbe..8b3775b55 100644 --- a/test/fuzz/fuzzer_replayer_test.cpp +++ b/test/fuzz/fuzzer_replayer_test.cpp @@ -951,7 +951,7 @@ TEST(FuzzerReplayerTest, Miscellaneous3) { { protobufs::FactConstantUniform resolution_x_eq_250; *resolution_x_eq_250.mutable_uniform_buffer_element_descriptor() = - MakeUniformBufferElementDescriptor(24, {0, 0}); + MakeUniformBufferElementDescriptor(0, 0, {0, 0}); *resolution_x_eq_250.mutable_constant_word()->Add() = 250; protobufs::Fact temp; *temp.mutable_constant_uniform_fact() = resolution_x_eq_250; @@ -960,7 +960,7 @@ TEST(FuzzerReplayerTest, Miscellaneous3) { { protobufs::FactConstantUniform resolution_y_eq_100; *resolution_y_eq_100.mutable_uniform_buffer_element_descriptor() = - MakeUniformBufferElementDescriptor(24, {0, 1}); + MakeUniformBufferElementDescriptor(0, 0, {0, 1}); *resolution_y_eq_100.mutable_constant_word()->Add() = 100; protobufs::Fact temp; *temp.mutable_constant_uniform_fact() = resolution_y_eq_100; diff --git a/test/fuzz/transformation_replace_constant_with_uniform_test.cpp b/test/fuzz/transformation_replace_constant_with_uniform_test.cpp index b3a0ccd2d..5a101732d 100644 --- a/test/fuzz/transformation_replace_constant_with_uniform_test.cpp +++ b/test/fuzz/transformation_replace_constant_with_uniform_test.cpp @@ -104,11 +104,11 @@ TEST(TransformationReplaceConstantWithUniformTest, BasicReplacements) { FactManager fact_manager; protobufs::UniformBufferElementDescriptor blockname_a = - MakeUniformBufferElementDescriptor(18, {0}); + MakeUniformBufferElementDescriptor(0, 0, {0}); protobufs::UniformBufferElementDescriptor blockname_b = - MakeUniformBufferElementDescriptor(18, {1}); + MakeUniformBufferElementDescriptor(0, 0, {1}); protobufs::UniformBufferElementDescriptor blockname_c = - MakeUniformBufferElementDescriptor(18, {2}); + MakeUniformBufferElementDescriptor(0, 0, {2}); ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 1, blockname_a)); ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 2, blockname_b)); @@ -157,9 +157,9 @@ TEST(TransformationReplaceConstantWithUniformTest, BasicReplacements) { // The following transformations do not apply because the uniform descriptors // are not sensible. protobufs::UniformBufferElementDescriptor nonsense_uniform_descriptor1 = - MakeUniformBufferElementDescriptor(19, {0}); + MakeUniformBufferElementDescriptor(1, 2, {0}); protobufs::UniformBufferElementDescriptor nonsense_uniform_descriptor2 = - MakeUniformBufferElementDescriptor(18, {5}); + MakeUniformBufferElementDescriptor(0, 0, {5}); ASSERT_FALSE(transformation::IsApplicable( transformation::MakeTransformationReplaceConstantWithUniform( use_of_9_in_store, nonsense_uniform_descriptor1, 101, 102), @@ -473,13 +473,13 @@ TEST(TransformationReplaceConstantWithUniformTest, NestedStruct) { FactManager fact_manager; protobufs::UniformBufferElementDescriptor blockname_1 = - MakeUniformBufferElementDescriptor(28, {0}); + MakeUniformBufferElementDescriptor(0, 0, {0}); protobufs::UniformBufferElementDescriptor blockname_2 = - MakeUniformBufferElementDescriptor(28, {1, 1}); + MakeUniformBufferElementDescriptor(0, 0, {1, 1}); protobufs::UniformBufferElementDescriptor blockname_3 = - MakeUniformBufferElementDescriptor(28, {1, 0, 0}); + MakeUniformBufferElementDescriptor(0, 0, {1, 0, 0}); protobufs::UniformBufferElementDescriptor blockname_4 = - MakeUniformBufferElementDescriptor(28, {1, 0, 1, 0}); + MakeUniformBufferElementDescriptor(0, 0, {1, 0, 1, 0}); ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 1, blockname_1)); ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 2, blockname_2)); @@ -712,7 +712,7 @@ TEST(TransformationReplaceConstantWithUniformTest, NoUniformIntPointerPresent) { FactManager fact_manager; protobufs::UniformBufferElementDescriptor blockname_0 = - MakeUniformBufferElementDescriptor(12, {0}); + MakeUniformBufferElementDescriptor(0, 0, {0}); ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 0, blockname_0)); @@ -786,9 +786,9 @@ TEST(TransformationReplaceConstantWithUniformTest, NoConstantPresentForIndex) { FactManager fact_manager; protobufs::UniformBufferElementDescriptor blockname_0 = - MakeUniformBufferElementDescriptor(12, {0}); + MakeUniformBufferElementDescriptor(0, 0, {0}); protobufs::UniformBufferElementDescriptor blockname_9 = - MakeUniformBufferElementDescriptor(12, {1}); + MakeUniformBufferElementDescriptor(0, 0, {1}); ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 9, blockname_9)); @@ -859,7 +859,7 @@ TEST(TransformationReplaceConstantWithUniformTest, FactManager fact_manager; protobufs::UniformBufferElementDescriptor blockname_3 = - MakeUniformBufferElementDescriptor(12, {0}); + MakeUniformBufferElementDescriptor(0, 0, {0}); uint32_t float_data[1]; float temp = 3.0; @@ -946,9 +946,9 @@ TEST(TransformationReplaceConstantWithUniformTest, FactManager fact_manager; protobufs::UniformBufferElementDescriptor blockname_9 = - MakeUniformBufferElementDescriptor(14, {0}); + MakeUniformBufferElementDescriptor(0, 0, {0}); protobufs::UniformBufferElementDescriptor blockname_10 = - MakeUniformBufferElementDescriptor(14, {1}); + MakeUniformBufferElementDescriptor(0, 0, {1}); ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 9, blockname_9)); ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), 10, blockname_10)); @@ -1172,42 +1172,42 @@ TEST(TransformationReplaceConstantWithUniformTest, ComplexReplacements) { memcpy(&float_vector_data, &float_vector_values, sizeof(float_vector_values)); protobufs::UniformBufferElementDescriptor uniform_f_a_0 = - MakeUniformBufferElementDescriptor(65, {0, 0, 0}); + MakeUniformBufferElementDescriptor(0, 0, {0, 0, 0}); protobufs::UniformBufferElementDescriptor uniform_f_a_1 = - MakeUniformBufferElementDescriptor(65, {0, 0, 1}); + MakeUniformBufferElementDescriptor(0, 0, {0, 0, 1}); protobufs::UniformBufferElementDescriptor uniform_f_a_2 = - MakeUniformBufferElementDescriptor(65, {0, 0, 2}); + MakeUniformBufferElementDescriptor(0, 0, {0, 0, 2}); protobufs::UniformBufferElementDescriptor uniform_f_a_3 = - MakeUniformBufferElementDescriptor(65, {0, 0, 3}); + MakeUniformBufferElementDescriptor(0, 0, {0, 0, 3}); protobufs::UniformBufferElementDescriptor uniform_f_a_4 = - MakeUniformBufferElementDescriptor(65, {0, 0, 4}); + MakeUniformBufferElementDescriptor(0, 0, {0, 0, 4}); protobufs::UniformBufferElementDescriptor uniform_f_b_x = - MakeUniformBufferElementDescriptor(65, {0, 1, 0}); + MakeUniformBufferElementDescriptor(0, 0, {0, 1, 0}); protobufs::UniformBufferElementDescriptor uniform_f_b_y = - MakeUniformBufferElementDescriptor(65, {0, 1, 1}); + MakeUniformBufferElementDescriptor(0, 0, {0, 1, 1}); protobufs::UniformBufferElementDescriptor uniform_f_b_z = - MakeUniformBufferElementDescriptor(65, {0, 1, 2}); + MakeUniformBufferElementDescriptor(0, 0, {0, 1, 2}); protobufs::UniformBufferElementDescriptor uniform_f_b_w = - MakeUniformBufferElementDescriptor(65, {0, 1, 3}); + MakeUniformBufferElementDescriptor(0, 0, {0, 1, 3}); protobufs::UniformBufferElementDescriptor uniform_f_c_x = - MakeUniformBufferElementDescriptor(65, {0, 2, 0}); + MakeUniformBufferElementDescriptor(0, 0, {0, 2, 0}); protobufs::UniformBufferElementDescriptor uniform_f_c_y = - MakeUniformBufferElementDescriptor(65, {0, 2, 1}); + MakeUniformBufferElementDescriptor(0, 0, {0, 2, 1}); protobufs::UniformBufferElementDescriptor uniform_f_c_z = - MakeUniformBufferElementDescriptor(65, {0, 2, 2}); + MakeUniformBufferElementDescriptor(0, 0, {0, 2, 2}); protobufs::UniformBufferElementDescriptor uniform_f_d = - MakeUniformBufferElementDescriptor(65, {0, 3}); + MakeUniformBufferElementDescriptor(0, 0, {0, 3}); protobufs::UniformBufferElementDescriptor uniform_g = - MakeUniformBufferElementDescriptor(65, {1}); + MakeUniformBufferElementDescriptor(0, 0, {1}); protobufs::UniformBufferElementDescriptor uniform_h_x = - MakeUniformBufferElementDescriptor(65, {2, 0}); + MakeUniformBufferElementDescriptor(0, 0, {2, 0}); protobufs::UniformBufferElementDescriptor uniform_h_y = - MakeUniformBufferElementDescriptor(65, {2, 1}); + MakeUniformBufferElementDescriptor(0, 0, {2, 1}); ASSERT_TRUE(AddFactHelper(&fact_manager, context.get(), float_array_data[0], uniform_f_a_0)); diff --git a/test/fuzz/uniform_buffer_element_descriptor_test.cpp b/test/fuzz/uniform_buffer_element_descriptor_test.cpp new file mode 100644 index 000000000..6c6d52a04 --- /dev/null +++ b/test/fuzz/uniform_buffer_element_descriptor_test.cpp @@ -0,0 +1,84 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/fuzz/uniform_buffer_element_descriptor.h" +#include "test/fuzz/fuzz_test_util.h" + +namespace spvtools { +namespace fuzz { +namespace { + +TEST(UniformBufferElementDescriptorTest, TestEquality) { + // Test that equality works as expected for various buffer element + // descriptors. + + protobufs::UniformBufferElementDescriptor descriptor1 = + MakeUniformBufferElementDescriptor(0, 0, {1, 2, 3}); + protobufs::UniformBufferElementDescriptor descriptor2 = + MakeUniformBufferElementDescriptor(0, 0, {1, 2, 3}); + protobufs::UniformBufferElementDescriptor descriptor3 = + MakeUniformBufferElementDescriptor(0, 1, {1, 2, 3}); + protobufs::UniformBufferElementDescriptor descriptor4 = + MakeUniformBufferElementDescriptor(1, 0, {1, 2, 3}); + protobufs::UniformBufferElementDescriptor descriptor5 = + MakeUniformBufferElementDescriptor(1, 1, {1, 2, 3}); + protobufs::UniformBufferElementDescriptor descriptor6 = + MakeUniformBufferElementDescriptor(0, 0, {1, 2, 4}); + protobufs::UniformBufferElementDescriptor descriptor7 = + MakeUniformBufferElementDescriptor(0, 0, {1, 2}); + + ASSERT_TRUE( + UniformBufferElementDescriptorEquals()(&descriptor1, &descriptor1)); + ASSERT_TRUE( + UniformBufferElementDescriptorEquals()(&descriptor1, &descriptor2)); + ASSERT_TRUE( + UniformBufferElementDescriptorEquals()(&descriptor3, &descriptor3)); + ASSERT_TRUE( + UniformBufferElementDescriptorEquals()(&descriptor4, &descriptor4)); + ASSERT_TRUE( + UniformBufferElementDescriptorEquals()(&descriptor5, &descriptor5)); + ASSERT_TRUE( + UniformBufferElementDescriptorEquals()(&descriptor6, &descriptor6)); + ASSERT_TRUE( + UniformBufferElementDescriptorEquals()(&descriptor7, &descriptor7)); + + ASSERT_FALSE( + UniformBufferElementDescriptorEquals()(&descriptor1, &descriptor3)); + ASSERT_FALSE( + UniformBufferElementDescriptorEquals()(&descriptor3, &descriptor1)); + + ASSERT_FALSE( + UniformBufferElementDescriptorEquals()(&descriptor1, &descriptor4)); + ASSERT_FALSE( + UniformBufferElementDescriptorEquals()(&descriptor4, &descriptor1)); + + ASSERT_FALSE( + UniformBufferElementDescriptorEquals()(&descriptor1, &descriptor5)); + ASSERT_FALSE( + UniformBufferElementDescriptorEquals()(&descriptor5, &descriptor1)); + + ASSERT_FALSE( + UniformBufferElementDescriptorEquals()(&descriptor1, &descriptor6)); + ASSERT_FALSE( + UniformBufferElementDescriptorEquals()(&descriptor6, &descriptor1)); + + ASSERT_FALSE( + UniformBufferElementDescriptorEquals()(&descriptor1, &descriptor7)); + ASSERT_FALSE( + UniformBufferElementDescriptorEquals()(&descriptor7, &descriptor1)); +} + +} // namespace +} // namespace fuzz +} // namespace spvtools