Skip to content

Commit

Permalink
instrument: Use Import linkage for instrumentation functions (Khronos…
Browse files Browse the repository at this point in the history
…Group#5355)

These functions are getting far too complicated to code in SPIRV-Tools
C++. Replace them with import stubs so that the real implementations
can live in Vulkan-ValidationLayers where they belong.

VVL will need to define these functions in spirv and link them to the
instrumented version of the user's shader.

From here on out, VVL can redefine the functions and any data they use
without updating SPIRV-Tools. Changing the function declarations will
still require both VVL and SPIRV-Tools to be updated in lock step.
  • Loading branch information
jeremyg-lunarg authored Sep 20, 2023
1 parent a40483d commit ee7598d
Show file tree
Hide file tree
Showing 15 changed files with 2,712 additions and 4,300 deletions.
122 changes: 0 additions & 122 deletions include/spirv-tools/instrument.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,71 +133,6 @@ static const int kInstTaskOutGlobalInvocationIdZ = kInstCommonOutCnt + 2;
// Size of Common and Stage-specific Members
static const int kInstStageOutCnt = kInstCommonOutCnt + 3;

// Validation Error Code Offset
//
// This identifies the validation error. It also helps to identify
// how many words follow in the record and their meaning.
static const int kInstValidationOutError = kInstStageOutCnt;

// Validation-specific Output Record Offsets
//
// Each different validation will generate a potentially different
// number of words at the end of the record giving more specifics
// about the validation error.
//
// A bindless bounds error will output the index and the bound.
static const int kInstBindlessBoundsOutDescSet = kInstStageOutCnt + 1;
static const int kInstBindlessBoundsOutDescBinding = kInstStageOutCnt + 2;
static const int kInstBindlessBoundsOutDescIndex = kInstStageOutCnt + 3;
static const int kInstBindlessBoundsOutDescBound = kInstStageOutCnt + 4;
static const int kInstBindlessBoundsOutUnused = kInstStageOutCnt + 5;
static const int kInstBindlessBoundsOutCnt = kInstStageOutCnt + 6;

// A descriptor uninitialized error will output the index.
static const int kInstBindlessUninitOutDescSet = kInstStageOutCnt + 1;
static const int kInstBindlessUninitOutBinding = kInstStageOutCnt + 2;
static const int kInstBindlessUninitOutDescIndex = kInstStageOutCnt + 3;
static const int kInstBindlessUninitOutUnused = kInstStageOutCnt + 4;
static const int kInstBindlessUninitOutUnused2 = kInstStageOutCnt + 5;
static const int kInstBindlessUninitOutCnt = kInstStageOutCnt + 6;

// A buffer out-of-bounds error will output the descriptor
// index, the buffer offset and the buffer size
static const int kInstBindlessBuffOOBOutDescSet = kInstStageOutCnt + 1;
static const int kInstBindlessBuffOOBOutDescBinding = kInstStageOutCnt + 2;
static const int kInstBindlessBuffOOBOutDescIndex = kInstStageOutCnt + 3;
static const int kInstBindlessBuffOOBOutBuffOff = kInstStageOutCnt + 4;
static const int kInstBindlessBuffOOBOutBuffSize = kInstStageOutCnt + 5;
static const int kInstBindlessBuffOOBOutCnt = kInstStageOutCnt + 6;

// A buffer address unalloc error will output the 64-bit pointer in
// two 32-bit pieces, lower bits first.
static const int kInstBuffAddrUnallocOutDescPtrLo = kInstStageOutCnt + 1;
static const int kInstBuffAddrUnallocOutDescPtrHi = kInstStageOutCnt + 2;
static const int kInstBuffAddrUnallocOutCnt = kInstStageOutCnt + 3;

// Maximum Output Record Member Count
static const int kInstMaxOutCnt = kInstStageOutCnt + 6;

// Validation Error Codes
//
// These are the possible validation error codes.
static const int kInstErrorBindlessBounds = 1;
static const int kInstErrorBindlessUninit = 2;
static const int kInstErrorBuffAddrUnallocRef = 3;
static const int kInstErrorOOB = 4;
static const int kInstErrorMax = kInstErrorOOB;

// Direct Input Buffer Offsets
//
// The following values provide member offsets into the input buffers
// consumed by InstrumentPass::GenDebugDirectRead(). This method is utilized
// by InstBindlessCheckPass.
//
// The only object in an input buffer is a runtime array of unsigned
// integers. Each validation will have its own formatting of this array.
static const int kDebugInputDataOffset = 0;

// Debug Buffer Bindings
//
// These are the bindings for the different buffers which are
Expand All @@ -216,63 +151,6 @@ static const int kDebugInputBindingBuffAddr = 2;
// This is the output buffer written by InstDebugPrintfPass.
static const int kDebugOutputPrintfStream = 3;

// clang-format off
// Bindless Validation Input Buffer Format
//
// An input buffer for bindless validation has this structure:
// GLSL:
// layout(buffer_reference, std430, buffer_reference_align = 8) buffer DescriptorSetData {
// uint num_bindings;
// uint data[];
// };
//
// layout(set = 7, binding = 1, std430) buffer inst_bindless_InputBuffer
// {
// DescriptorSetData desc_sets[32];
// } inst_bindless_input_buffer;
//
//
// To look up the length of a binding:
// uint length = inst_bindless_input_buffer[set].data[binding];
// Scalar bindings have a length of 1.
//
// To look up the initialization state of a descriptor in a binding:
// uint num_bindings = inst_bindless_input_buffer[set].num_bindings;
// uint binding_state_start = inst_bindless_input_buffer[set].data[num_bindings + binding];
// uint init_state = inst_bindless_input_buffer[set].data[binding_state_start + index];
//
// For scalar bindings, use 0 for the index.
// clang-format on
//
// The size of the inst_bindless_input_buffer array, regardless of how many
// descriptor sets the device supports.
static const int kDebugInputBindlessMaxDescSets = 32;

// Buffer Device Address Input Buffer Format
//
// An input buffer for buffer device address validation consists of a single
// array of unsigned 64-bit integers we will call Data[]. This array is
// formatted as follows:
//
// At offset kDebugInputBuffAddrPtrOffset is a list of sorted valid buffer
// addresses. The list is terminated with the address 0xffffffffffffffff.
// If 0x0 is not a valid buffer address, this address is inserted at the
// start of the list.
//
static const int kDebugInputBuffAddrPtrOffset = 1;
//
// At offset kDebugInputBuffAddrLengthOffset in Data[] is a single uint64 which
// gives an offset to the start of the buffer length data. More
// specifically, for a buffer whose pointer is located at input buffer offset
// i, the length is located at:
//
// Data[ i - kDebugInputBuffAddrPtrOffset
// + Data[ kDebugInputBuffAddrLengthOffset ] ]
//
// The length associated with the 0xffffffffffffffff address is zero. If
// not a valid buffer, the length associated with the 0x0 address is zero.
static const int kDebugInputBuffAddrLengthOffset = 0;

} // namespace spvtools

#endif // INCLUDE_SPIRV_TOOLS_INSTRUMENT_HPP_
9 changes: 3 additions & 6 deletions include/spirv-tools/optimizer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -766,11 +766,9 @@ Optimizer::PassToken CreateCombineAccessChainsPass();
// potentially de-optimizing the instrument code, for example, inlining
// the debug record output function throughout the module.
//
// The instrumentation will read and write buffers in debug
// descriptor set |desc_set|. It will write |shader_id| in each output record
// The instrumentation will write |shader_id| in each output record
// to identify the shader module which generated the record.
Optimizer::PassToken CreateInstBindlessCheckPass(uint32_t desc_set,
uint32_t shader_id);
Optimizer::PassToken CreateInstBindlessCheckPass(uint32_t shader_id);

// Create a pass to instrument physical buffer address checking
// This pass instruments all physical buffer address references to check that
Expand All @@ -791,8 +789,7 @@ Optimizer::PassToken CreateInstBindlessCheckPass(uint32_t desc_set,
// The instrumentation will read and write buffers in debug
// descriptor set |desc_set|. It will write |shader_id| in each output record
// to identify the shader module which generated the record.
Optimizer::PassToken CreateInstBuffAddrCheckPass(uint32_t desc_set,
uint32_t shader_id);
Optimizer::PassToken CreateInstBuffAddrCheckPass(uint32_t shader_id);

// Create a pass to instrument OpDebugPrintf instructions.
// This pass replaces all OpDebugPrintf instructions with instructions to write
Expand Down
Loading

0 comments on commit ee7598d

Please sign in to comment.