Represent uniform facts via descriptor set and binding. (#2681)

* Represent uniform facts via descriptor set and binding.

Previously uniform facts were expressed with resepect to the id of a
uniform variable.  Describing them with respect to a descriptor set
and binding is more convenient from the point of view of expressing
facts about a shader without requiring analysis of its SPIR-V.

* Fix equality testing for uniform buffer element descriptors.

The equality test now checks that the lengths of the index vectors
match.  Added a test that exposes the previous omission.
This commit is contained in:
Alastair Donaldson 2019-06-19 20:45:14 +01:00 committed by GitHub
parent fa981bc245
commit 51b0d5ce50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 389 additions and 95 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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<opt::Instruction> 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;

View File

@ -14,13 +14,17 @@
#include "source/fuzz/uniform_buffer_element_descriptor.h"
#include <source/opt/instruction.h>
namespace spvtools {
namespace fuzz {
protobufs::UniformBufferElementDescriptor MakeUniformBufferElementDescriptor(
uint32_t uniform_variable_id, std::vector<uint32_t>&& indices) {
uint32_t descriptor_set, uint32_t binding,
std::vector<uint32_t>&& 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

View File

@ -19,6 +19,8 @@
#include <vector>
#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<uint32_t>&& indices);
uint32_t descriptor_set, uint32_t binding, std::vector<uint32_t>&& 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

View File

@ -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}

View File

@ -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<float>::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

View File

@ -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

View File

@ -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;

View File

@ -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));

View File

@ -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