mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-17 20:52:36 +01:00
Updated spirv-tools.
This commit is contained in:
92
3rdparty/spirv-tools/CHANGES
vendored
92
3rdparty/spirv-tools/CHANGES
vendored
@@ -1,7 +1,95 @@
|
||||
Revision history for SPIRV-Tools
|
||||
|
||||
v2020.6 2020-09-24
|
||||
- Start SPIRV-Tools v2020.6
|
||||
v2020.7-dev 2020-12-03
|
||||
- Start v2020.7-dev
|
||||
|
||||
v2020.6 2020-12-02
|
||||
- General
|
||||
CMake: Add SPIRV_TOOLS_BUILD_STATIC flag (#3910)
|
||||
- Disassembler
|
||||
Add some context comments to disassembly. (#3847)
|
||||
- Optimizer
|
||||
- Do run DCE if SPV_KHR_ray_query is used. (#4047)
|
||||
- Handle 8-bit index in elim dead member (#4043)
|
||||
- Add texel buffer out-of-bounds checking instrumentation (#4038)
|
||||
- Update MeshShadingNV dependencies (and land Ray tracing updates) (#4028)
|
||||
- Fix buffer oob instrumentation for matrix refs (#4025)
|
||||
- Fix SSA re-writing in the presence of variable pointers. (#4010)
|
||||
- Add support to prevent functions from being inlined if they have
|
||||
DontInline flag (#3858)
|
||||
- Add SPV_EXT_shader_image_int64 (#3852)
|
||||
- Support SPV_KHR_fragment_shading_rate (#3943)
|
||||
- Fix use-after-move in val/validate.cpp (#3848)
|
||||
- Debug Info
|
||||
- properly preserve DebugValue indexes operand (#4022)
|
||||
- Add DebugValue for invisible store in single_store_elim (#4002)
|
||||
- Propagate OpLine to all applied instructions in spirv-opt (#3951)
|
||||
- Add DebugValue for DebugDecl invisible to value assignment (#3973)
|
||||
- Add DebugValue for function param regardless of scope (#3923)
|
||||
- Debug info preservation in convert-local-access-chains pass (#3835)
|
||||
- Debug info preservation in redundancy-elimination pass (#3839)
|
||||
- Debug info preservation in if-conversion pass (#3861)
|
||||
- Validator
|
||||
- Add validation support for the ray tracing built-in variables (#4041)
|
||||
- Use less stack space when validating Vulkan builtins (#4019)
|
||||
- Fix SPV_KHR_fragment_shading_rate VUID label (#4014)
|
||||
- Label Layer and ViewportIndex VUIDs (#4013)
|
||||
- Allow the ViewportIndex and Layer built-ins on SPIR-V 1.5 (#3986)
|
||||
- Fix validation of OpPhi instructions (#3919)
|
||||
- Fuzz
|
||||
- Fix facts arising from CompositeConstruct (#4034)
|
||||
- Do not flatten conditionals that create synonyms (#4030)
|
||||
- Add support for reining in rogue fuzzer passes (#3987)
|
||||
- Fix assertion failure in FuzzerPassAddCompositeExtract (#3995)
|
||||
- Fix invalid equation facts (#4009)
|
||||
- Fix bugs in TransformationFlattenConditionalBranch (#4006)
|
||||
- Fix bug related to transformation applicability (#3990)
|
||||
- Add expand vector reduction transformation (#3869)
|
||||
- Add FuzzerPassAddCompositeExtract (#3904)
|
||||
- Fix mismatch with shrinker step limit (#3985)
|
||||
- Fix off-by-one error in replayer (#3982)
|
||||
- Get order right for OpSelect arguments (#3974)
|
||||
- Do not add synonym-creating loops in dead blocks (#3975)
|
||||
- Skip OpTypeSampledImage when propagating up (#3976)
|
||||
- Pass OpUndef in function call if needed (#3978)
|
||||
- Fix off-by-one in TransformationCompositeConstruct (#3979)
|
||||
- Tolerate absent ids in data synonym fact management (#3966)
|
||||
- Fix to id availability (#3971)
|
||||
- Fix operand types (#3962)
|
||||
- Don't flatten conditional if condition is irrelevant (#3944)
|
||||
- Do not produce OpPhis of type OpTypeSampledImage (#3964)
|
||||
- Restrict fuzzer pass to reachable blocks (#3970)
|
||||
- Handle more types when extending OpPhi instructions (#3969)
|
||||
- Skip early terminator wrappers when merging returns (#3968)
|
||||
- Avoid irrelevant constants in synonym-creating loops (#3967)
|
||||
- Skip dead blocks in FuzzerPassAddOpPhiSynonyms (#3965)
|
||||
- Avoid the type manager when looking for struct types (#3963)
|
||||
- Fix to TransformationDuplicateRegionWithSelection (#3941)
|
||||
- Skip OpFunction when replacing irrelevant ids (#3932)
|
||||
- Use component-wise selectors when flattening conditional branches (#3921)
|
||||
- Avoid void struct member when outlining functions (#3936)
|
||||
- Do not allow Block-decorated structs when adding parameters (#3931)
|
||||
- Fix to operand id type (#3937)
|
||||
- Handle dead blocks in TransformationEquationInstruction (#3933)
|
||||
- Do not allow sampled image load when flattening conditionals (#3930)
|
||||
- Take care of OpPhi instructions when inlining (#3939)
|
||||
- Fix to TransformationInlineFunction (#3913)
|
||||
- Wrap early terminators before merging returns (#3925)
|
||||
- Lower probability of adding bit instruction synonyms (#3917)
|
||||
- Fix handling of OpPhi in FlattenConditionalBranch (#3916)
|
||||
- Avoid creating blocks without parents (#3908)
|
||||
- Do not allow creation of constants of block-decorated structs (#3903)
|
||||
- Fixes related to irrelevant ids (#3901)
|
||||
- Fix to transformation that adds a synonym via a loop (#3898)
|
||||
- Fix to duplicate region with selection (#3896)
|
||||
- Do not expose synonym facts for non-existent ids (#3891)
|
||||
- Do not add synonyms involving irrelevant ids (#3890)
|
||||
- Do not replace irrelevant ids that are not in blocks (#3892)
|
||||
- Wrap OpKill and similar in function calls (#3884)
|
||||
- Integrate spirv-reduce with shrinker (#3849)
|
||||
- Report fresh ids in transformations (#3856)
|
||||
- Support OpNot bit instruction case (#3841)
|
||||
- Return IR and transformation context after replay (#3846)
|
||||
|
||||
v2020.5 2020-09-22
|
||||
- General
|
||||
|
||||
@@ -1 +1 @@
|
||||
"v2020.6", "SPIRV-Tools v2020.6 475fea23bc1061461168fd99de41ebc8ee321b3b"
|
||||
"v2020.7-dev", "SPIRV-Tools v2020.7-dev c73d8d8cf8076c3848338cc5a5f63d291afa2989"
|
||||
|
||||
@@ -171,6 +171,10 @@ static const int kInstErrorBindlessBounds = 0;
|
||||
static const int kInstErrorBindlessUninit = 1;
|
||||
static const int kInstErrorBuffAddrUnallocRef = 2;
|
||||
static const int kInstErrorBindlessBuffOOB = 3;
|
||||
static const int kInstErrorBuffOOBUniform = 4;
|
||||
static const int kInstErrorBuffOOBStorage = 5;
|
||||
static const int kInstErrorBuffOOBUniformTexel = 6;
|
||||
static const int kInstErrorBuffOOBStorageTexel = 7;
|
||||
|
||||
// Direct Input Buffer Offsets
|
||||
//
|
||||
|
||||
@@ -747,12 +747,16 @@ Optimizer::PassToken CreateCombineAccessChainsPass();
|
||||
// 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.
|
||||
// |input_length_enable| controls instrumentation of runtime descriptor array
|
||||
// references, and |input_init_enable| controls instrumentation of descriptor
|
||||
// initialization checking, both of which require input buffer support.
|
||||
// |desc_length_enable| controls instrumentation of runtime descriptor array
|
||||
// references, |desc_init_enable| controls instrumentation of descriptor
|
||||
// initialization checking, and |buff_oob_enable| controls instrumentation
|
||||
// of storage and uniform buffer bounds checking, all of which require input
|
||||
// buffer support. |texbuff_oob_enable| controls instrumentation of texel
|
||||
// buffers, which does not require input buffer support.
|
||||
Optimizer::PassToken CreateInstBindlessCheckPass(
|
||||
uint32_t desc_set, uint32_t shader_id, bool input_length_enable = false,
|
||||
bool input_init_enable = false, bool input_buff_oob_enable = false);
|
||||
uint32_t desc_set, uint32_t shader_id, bool desc_length_enable = false,
|
||||
bool desc_init_enable = false, bool buff_oob_enable = false,
|
||||
bool texbuff_oob_enable = false);
|
||||
|
||||
// Create a pass to instrument physical buffer address checking
|
||||
// This pass instruments all physical buffer address references to check that
|
||||
|
||||
@@ -991,6 +991,7 @@ void AggressiveDCEPass::InitExtensions() {
|
||||
"SPV_NV_mesh_shader",
|
||||
"SPV_NV_ray_tracing",
|
||||
"SPV_KHR_ray_tracing",
|
||||
"SPV_KHR_ray_query",
|
||||
"SPV_EXT_fragment_invocation_density",
|
||||
"SPV_EXT_physical_storage_buffer",
|
||||
"SPV_KHR_terminate_invocation",
|
||||
|
||||
@@ -228,15 +228,10 @@ void EliminateDeadMembersPass::MarkMembersAsLiveForAccessChain(
|
||||
const_mgr->FindDeclaredConstant(inst->GetSingleWordInOperand(i))
|
||||
->AsIntConstant();
|
||||
assert(member_idx);
|
||||
if (member_idx->type()->AsInteger()->width() == 32) {
|
||||
used_members_[type_id].insert(member_idx->GetU32());
|
||||
type_id = type_inst->GetSingleWordInOperand(member_idx->GetU32());
|
||||
} else {
|
||||
used_members_[type_id].insert(
|
||||
static_cast<uint32_t>(member_idx->GetU64()));
|
||||
type_id = type_inst->GetSingleWordInOperand(
|
||||
static_cast<uint32_t>(member_idx->GetU64()));
|
||||
}
|
||||
uint32_t index =
|
||||
static_cast<uint32_t>(member_idx->GetZeroExtendedValue());
|
||||
used_members_[type_id].insert(index);
|
||||
type_id = type_inst->GetSingleWordInOperand(index);
|
||||
} break;
|
||||
case SpvOpTypeArray:
|
||||
case SpvOpTypeRuntimeArray:
|
||||
@@ -477,12 +472,8 @@ bool EliminateDeadMembersPass::UpdateAccessChain(Instruction* inst) {
|
||||
const_mgr->FindDeclaredConstant(inst->GetSingleWordInOperand(i))
|
||||
->AsIntConstant();
|
||||
assert(member_idx);
|
||||
uint32_t orig_member_idx;
|
||||
if (member_idx->type()->AsInteger()->width() == 32) {
|
||||
orig_member_idx = member_idx->GetU32();
|
||||
} else {
|
||||
orig_member_idx = static_cast<uint32_t>(member_idx->GetU64());
|
||||
}
|
||||
uint32_t orig_member_idx =
|
||||
static_cast<uint32_t>(member_idx->GetZeroExtendedValue());
|
||||
uint32_t new_member_idx = GetNewMemberIndex(type_id, orig_member_idx);
|
||||
assert(new_member_idx != kRemovedMember);
|
||||
if (orig_member_idx != new_member_idx) {
|
||||
|
||||
@@ -23,13 +23,17 @@ static const int kSpvImageSampleImageIdInIdx = 0;
|
||||
static const int kSpvSampledImageImageIdInIdx = 0;
|
||||
static const int kSpvSampledImageSamplerIdInIdx = 1;
|
||||
static const int kSpvImageSampledImageIdInIdx = 0;
|
||||
static const int kSpvCopyObjectOperandIdInIdx = 0;
|
||||
static const int kSpvLoadPtrIdInIdx = 0;
|
||||
static const int kSpvAccessChainBaseIdInIdx = 0;
|
||||
static const int kSpvAccessChainIndex0IdInIdx = 1;
|
||||
static const int kSpvTypeArrayLengthIdInIdx = 1;
|
||||
static const int kSpvConstantValueInIdx = 0;
|
||||
static const int kSpvVariableStorageClassInIdx = 0;
|
||||
|
||||
static const int kSpvTypeImageDim = 1;
|
||||
static const int kSpvTypeImageDepth = 2;
|
||||
static const int kSpvTypeImageArrayed = 3;
|
||||
static const int kSpvTypeImageMS = 4;
|
||||
} // anonymous namespace
|
||||
|
||||
// Avoid unused variable warning/error on Linux
|
||||
@@ -75,42 +79,51 @@ uint32_t InstBindlessCheckPass::GenDebugReadInit(uint32_t var_id,
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t InstBindlessCheckPass::CloneOriginalImage(
|
||||
uint32_t old_image_id, InstructionBuilder* builder) {
|
||||
Instruction* new_image_inst;
|
||||
Instruction* old_image_inst = get_def_use_mgr()->GetDef(old_image_id);
|
||||
if (old_image_inst->opcode() == SpvOpLoad) {
|
||||
new_image_inst = builder->AddLoad(
|
||||
old_image_inst->type_id(),
|
||||
old_image_inst->GetSingleWordInOperand(kSpvLoadPtrIdInIdx));
|
||||
} else if (old_image_inst->opcode() == SpvOp::SpvOpSampledImage) {
|
||||
uint32_t clone_id = CloneOriginalImage(
|
||||
old_image_inst->GetSingleWordInOperand(kSpvSampledImageImageIdInIdx),
|
||||
builder);
|
||||
new_image_inst = builder->AddBinaryOp(
|
||||
old_image_inst->type_id(), SpvOpSampledImage, clone_id,
|
||||
old_image_inst->GetSingleWordInOperand(kSpvSampledImageSamplerIdInIdx));
|
||||
} else if (old_image_inst->opcode() == SpvOp::SpvOpImage) {
|
||||
uint32_t clone_id = CloneOriginalImage(
|
||||
old_image_inst->GetSingleWordInOperand(kSpvImageSampledImageIdInIdx),
|
||||
builder);
|
||||
new_image_inst =
|
||||
builder->AddUnaryOp(old_image_inst->type_id(), SpvOpImage, clone_id);
|
||||
} else {
|
||||
assert(old_image_inst->opcode() == SpvOp::SpvOpCopyObject &&
|
||||
"expecting OpCopyObject");
|
||||
uint32_t clone_id = CloneOriginalImage(
|
||||
old_image_inst->GetSingleWordInOperand(kSpvCopyObjectOperandIdInIdx),
|
||||
builder);
|
||||
// Since we are cloning, no need to create new copy
|
||||
new_image_inst = get_def_use_mgr()->GetDef(clone_id);
|
||||
}
|
||||
uid2offset_[new_image_inst->unique_id()] =
|
||||
uid2offset_[old_image_inst->unique_id()];
|
||||
uint32_t new_image_id = new_image_inst->result_id();
|
||||
get_decoration_mgr()->CloneDecorations(old_image_id, new_image_id);
|
||||
return new_image_id;
|
||||
}
|
||||
|
||||
uint32_t InstBindlessCheckPass::CloneOriginalReference(
|
||||
ref_analysis* ref, InstructionBuilder* builder) {
|
||||
RefAnalysis* ref, InstructionBuilder* builder) {
|
||||
// If original is image based, start by cloning descriptor load
|
||||
uint32_t new_image_id = 0;
|
||||
if (ref->desc_load_id != 0) {
|
||||
Instruction* desc_load_inst = get_def_use_mgr()->GetDef(ref->desc_load_id);
|
||||
Instruction* new_load_inst = builder->AddLoad(
|
||||
desc_load_inst->type_id(),
|
||||
desc_load_inst->GetSingleWordInOperand(kSpvLoadPtrIdInIdx));
|
||||
uid2offset_[new_load_inst->unique_id()] =
|
||||
uid2offset_[desc_load_inst->unique_id()];
|
||||
uint32_t new_load_id = new_load_inst->result_id();
|
||||
get_decoration_mgr()->CloneDecorations(desc_load_inst->result_id(),
|
||||
new_load_id);
|
||||
new_image_id = new_load_id;
|
||||
// Clone Image/SampledImage with new load, if needed
|
||||
if (ref->image_id != 0) {
|
||||
Instruction* image_inst = get_def_use_mgr()->GetDef(ref->image_id);
|
||||
if (image_inst->opcode() == SpvOp::SpvOpSampledImage) {
|
||||
Instruction* new_image_inst = builder->AddBinaryOp(
|
||||
image_inst->type_id(), SpvOpSampledImage, new_load_id,
|
||||
image_inst->GetSingleWordInOperand(kSpvSampledImageSamplerIdInIdx));
|
||||
uid2offset_[new_image_inst->unique_id()] =
|
||||
uid2offset_[image_inst->unique_id()];
|
||||
new_image_id = new_image_inst->result_id();
|
||||
} else {
|
||||
assert(image_inst->opcode() == SpvOp::SpvOpImage &&
|
||||
"expecting OpImage");
|
||||
Instruction* new_image_inst =
|
||||
builder->AddUnaryOp(image_inst->type_id(), SpvOpImage, new_load_id);
|
||||
uid2offset_[new_image_inst->unique_id()] =
|
||||
uid2offset_[image_inst->unique_id()];
|
||||
new_image_id = new_image_inst->result_id();
|
||||
}
|
||||
get_decoration_mgr()->CloneDecorations(ref->image_id, new_image_id);
|
||||
}
|
||||
uint32_t old_image_id =
|
||||
ref->ref_inst->GetSingleWordInOperand(kSpvImageSampleImageIdInIdx);
|
||||
new_image_id = CloneOriginalImage(old_image_id, builder);
|
||||
}
|
||||
// Clone original reference
|
||||
std::unique_ptr<Instruction> new_ref_inst(ref->ref_inst->Clone(context()));
|
||||
@@ -179,7 +192,7 @@ Instruction* InstBindlessCheckPass::GetPointeeTypeInst(Instruction* ptr_inst) {
|
||||
}
|
||||
|
||||
bool InstBindlessCheckPass::AnalyzeDescriptorReference(Instruction* ref_inst,
|
||||
ref_analysis* ref) {
|
||||
RefAnalysis* ref) {
|
||||
ref->ref_inst = ref_inst;
|
||||
if (ref_inst->opcode() == SpvOpLoad || ref_inst->opcode() == SpvOpStore) {
|
||||
ref->desc_load_id = 0;
|
||||
@@ -220,25 +233,28 @@ bool InstBindlessCheckPass::AnalyzeDescriptorReference(Instruction* ref_inst,
|
||||
// Reference is not load or store. If not an image-based reference, return.
|
||||
ref->image_id = GetImageId(ref_inst);
|
||||
if (ref->image_id == 0) return false;
|
||||
Instruction* image_inst = get_def_use_mgr()->GetDef(ref->image_id);
|
||||
Instruction* desc_load_inst = nullptr;
|
||||
if (image_inst->opcode() == SpvOp::SpvOpSampledImage) {
|
||||
ref->desc_load_id =
|
||||
image_inst->GetSingleWordInOperand(kSpvSampledImageImageIdInIdx);
|
||||
desc_load_inst = get_def_use_mgr()->GetDef(ref->desc_load_id);
|
||||
} else if (image_inst->opcode() == SpvOp::SpvOpImage) {
|
||||
ref->desc_load_id =
|
||||
image_inst->GetSingleWordInOperand(kSpvImageSampledImageIdInIdx);
|
||||
desc_load_inst = get_def_use_mgr()->GetDef(ref->desc_load_id);
|
||||
} else {
|
||||
ref->desc_load_id = ref->image_id;
|
||||
desc_load_inst = image_inst;
|
||||
ref->image_id = 0;
|
||||
// Search for descriptor load
|
||||
uint32_t desc_load_id = ref->image_id;
|
||||
Instruction* desc_load_inst;
|
||||
for (;;) {
|
||||
desc_load_inst = get_def_use_mgr()->GetDef(desc_load_id);
|
||||
if (desc_load_inst->opcode() == SpvOp::SpvOpSampledImage)
|
||||
desc_load_id =
|
||||
desc_load_inst->GetSingleWordInOperand(kSpvSampledImageImageIdInIdx);
|
||||
else if (desc_load_inst->opcode() == SpvOp::SpvOpImage)
|
||||
desc_load_id =
|
||||
desc_load_inst->GetSingleWordInOperand(kSpvImageSampledImageIdInIdx);
|
||||
else if (desc_load_inst->opcode() == SpvOp::SpvOpCopyObject)
|
||||
desc_load_id =
|
||||
desc_load_inst->GetSingleWordInOperand(kSpvCopyObjectOperandIdInIdx);
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (desc_load_inst->opcode() != SpvOp::SpvOpLoad) {
|
||||
// TODO(greg-lunarg): Handle additional possibilities?
|
||||
return false;
|
||||
}
|
||||
ref->desc_load_id = desc_load_id;
|
||||
ref->ptr_id = desc_load_inst->GetSingleWordInOperand(kSpvLoadPtrIdInIdx);
|
||||
Instruction* ptr_inst = get_def_use_mgr()->GetDef(ref->ptr_id);
|
||||
if (ptr_inst->opcode() == SpvOp::SpvOpVariable) {
|
||||
@@ -322,7 +338,7 @@ uint32_t InstBindlessCheckPass::ByteSize(uint32_t ty_id, uint32_t matrix_stride,
|
||||
return size;
|
||||
}
|
||||
|
||||
uint32_t InstBindlessCheckPass::GenLastByteIdx(ref_analysis* ref,
|
||||
uint32_t InstBindlessCheckPass::GenLastByteIdx(RefAnalysis* ref,
|
||||
InstructionBuilder* builder) {
|
||||
// Find outermost buffer type and its access chain index
|
||||
Instruction* var_inst = get_def_use_mgr()->GetDef(ref->var_id);
|
||||
@@ -474,7 +490,7 @@ uint32_t InstBindlessCheckPass::GenLastByteIdx(ref_analysis* ref,
|
||||
|
||||
void InstBindlessCheckPass::GenCheckCode(
|
||||
uint32_t check_id, uint32_t error_id, uint32_t offset_id,
|
||||
uint32_t length_id, uint32_t stage_idx, ref_analysis* ref,
|
||||
uint32_t length_id, uint32_t stage_idx, RefAnalysis* ref,
|
||||
std::vector<std::unique_ptr<BasicBlock>>* new_blocks) {
|
||||
BasicBlock* back_blk_ptr = &*new_blocks->back();
|
||||
InstructionBuilder builder(
|
||||
@@ -508,7 +524,7 @@ void InstBindlessCheckPass::GenCheckCode(
|
||||
GenDebugStreamWrite(uid2offset_[ref->ref_inst->unique_id()], stage_idx,
|
||||
{error_id, u_index_id, u_offset_id, u_length_id},
|
||||
&builder);
|
||||
} else if (buffer_bounds_enabled_) {
|
||||
} else if (buffer_bounds_enabled_ || texel_buffer_enabled_) {
|
||||
// Uninitialized Descriptor - Return additional unused zero so all error
|
||||
// modes will use same debug stream write function
|
||||
uint32_t u_length_id = GenUintCastCode(length_id, &builder);
|
||||
@@ -551,7 +567,7 @@ void InstBindlessCheckPass::GenDescIdxCheckCode(
|
||||
std::vector<std::unique_ptr<BasicBlock>>* new_blocks) {
|
||||
// Look for reference through indexed descriptor. If found, analyze and
|
||||
// save components. If not, return.
|
||||
ref_analysis ref;
|
||||
RefAnalysis ref;
|
||||
if (!AnalyzeDescriptorReference(&*ref_inst_itr, &ref)) return;
|
||||
Instruction* ptr_inst = get_def_use_mgr()->GetDef(ref.ptr_id);
|
||||
if (ptr_inst->opcode() != SpvOp::SpvOpAccessChain) return;
|
||||
@@ -610,7 +626,7 @@ void InstBindlessCheckPass::GenDescInitCheckCode(
|
||||
UptrVectorIterator<BasicBlock> ref_block_itr, uint32_t stage_idx,
|
||||
std::vector<std::unique_ptr<BasicBlock>>* new_blocks) {
|
||||
// Look for reference through descriptor. If not, return.
|
||||
ref_analysis ref;
|
||||
RefAnalysis ref;
|
||||
if (!AnalyzeDescriptorReference(&*ref_inst_itr, &ref)) return;
|
||||
// Determine if we can only do initialization check
|
||||
bool init_check = false;
|
||||
@@ -661,12 +677,77 @@ void InstBindlessCheckPass::GenDescInitCheckCode(
|
||||
MovePostludeCode(ref_block_itr, back_blk_ptr);
|
||||
}
|
||||
|
||||
void InstBindlessCheckPass::GenTexBuffCheckCode(
|
||||
BasicBlock::iterator ref_inst_itr,
|
||||
UptrVectorIterator<BasicBlock> ref_block_itr, uint32_t stage_idx,
|
||||
std::vector<std::unique_ptr<BasicBlock>>* new_blocks) {
|
||||
// Only process OpImageRead and OpImageWrite with no optional operands
|
||||
Instruction* ref_inst = &*ref_inst_itr;
|
||||
SpvOp op = ref_inst->opcode();
|
||||
uint32_t num_in_oprnds = ref_inst->NumInOperands();
|
||||
if (!((op == SpvOpImageRead && num_in_oprnds == 2) ||
|
||||
(op == SpvOpImageFetch && num_in_oprnds == 2) ||
|
||||
(op == SpvOpImageWrite && num_in_oprnds == 3)))
|
||||
return;
|
||||
// Pull components from descriptor reference
|
||||
RefAnalysis ref;
|
||||
if (!AnalyzeDescriptorReference(ref_inst, &ref)) return;
|
||||
// Only process if image is texel buffer
|
||||
Instruction* image_inst = get_def_use_mgr()->GetDef(ref.image_id);
|
||||
uint32_t image_ty_id = image_inst->type_id();
|
||||
Instruction* image_ty_inst = get_def_use_mgr()->GetDef(image_ty_id);
|
||||
if (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageDim) != SpvDimBuffer)
|
||||
return;
|
||||
if (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageDepth) != 0) return;
|
||||
if (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageArrayed) != 0) return;
|
||||
if (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageMS) != 0) return;
|
||||
// Enable ImageQuery Capability if not yet enabled
|
||||
if (!get_feature_mgr()->HasCapability(SpvCapabilityImageQuery)) {
|
||||
std::unique_ptr<Instruction> cap_image_query_inst(new Instruction(
|
||||
context(), SpvOpCapability, 0, 0,
|
||||
std::initializer_list<Operand>{
|
||||
{SPV_OPERAND_TYPE_CAPABILITY, {SpvCapabilityImageQuery}}}));
|
||||
get_def_use_mgr()->AnalyzeInstDefUse(&*cap_image_query_inst);
|
||||
context()->AddCapability(std::move(cap_image_query_inst));
|
||||
}
|
||||
// Move original block's preceding instructions into first new block
|
||||
std::unique_ptr<BasicBlock> new_blk_ptr;
|
||||
MovePreludeCode(ref_inst_itr, ref_block_itr, &new_blk_ptr);
|
||||
InstructionBuilder builder(
|
||||
context(), &*new_blk_ptr,
|
||||
IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
|
||||
new_blocks->push_back(std::move(new_blk_ptr));
|
||||
// Get texel coordinate
|
||||
uint32_t coord_id =
|
||||
GenUintCastCode(ref_inst->GetSingleWordInOperand(1), &builder);
|
||||
// If index id not yet set, binding is single descriptor, so set index to
|
||||
// constant 0.
|
||||
if (ref.desc_idx_id == 0) ref.desc_idx_id = builder.GetUintConstantId(0u);
|
||||
// Get texel buffer size.
|
||||
Instruction* size_inst =
|
||||
builder.AddUnaryOp(GetUintId(), SpvOpImageQuerySize, ref.image_id);
|
||||
uint32_t size_id = size_inst->result_id();
|
||||
// Generate runtime initialization/bounds test code with true branch
|
||||
// being full reference and false branch being debug output and zero
|
||||
// for the referenced value.
|
||||
Instruction* ult_inst =
|
||||
builder.AddBinaryOp(GetBoolId(), SpvOpULessThan, coord_id, size_id);
|
||||
uint32_t error_id = builder.GetUintConstantId(kInstErrorBindlessBuffOOB);
|
||||
GenCheckCode(ult_inst->result_id(), error_id, coord_id, size_id, stage_idx,
|
||||
&ref, new_blocks);
|
||||
// Move original block's remaining code into remainder/merge block and add
|
||||
// to new blocks
|
||||
BasicBlock* back_blk_ptr = &*new_blocks->back();
|
||||
MovePostludeCode(ref_block_itr, back_blk_ptr);
|
||||
}
|
||||
|
||||
void InstBindlessCheckPass::InitializeInstBindlessCheck() {
|
||||
// Initialize base class
|
||||
InitializeInstrument();
|
||||
// If runtime array length support enabled, create variable mappings. Length
|
||||
// support is always enabled if descriptor init check is enabled.
|
||||
if (desc_idx_enabled_ || buffer_bounds_enabled_)
|
||||
// If runtime array length support or buffer bounds checking are enabled,
|
||||
// create variable mappings. Length support is always enabled if descriptor
|
||||
// init check is enabled.
|
||||
if (desc_idx_enabled_ || buffer_bounds_enabled_ || texel_buffer_enabled_)
|
||||
for (auto& anno : get_module()->annotations())
|
||||
if (anno.opcode() == SpvOpDecorate) {
|
||||
if (anno.GetSingleWordInOperand(1u) == SpvDecorationDescriptorSet)
|
||||
@@ -689,8 +770,8 @@ Pass::Status InstBindlessCheckPass::ProcessImpl() {
|
||||
};
|
||||
bool modified = InstProcessEntryPointCallTree(pfn);
|
||||
if (desc_init_enabled_ || buffer_bounds_enabled_) {
|
||||
// Perform descriptor initialization check on each entry point function in
|
||||
// module
|
||||
// Perform descriptor initialization and/or buffer bounds check on each
|
||||
// entry point function in module
|
||||
pfn = [this](BasicBlock::iterator ref_inst_itr,
|
||||
UptrVectorIterator<BasicBlock> ref_block_itr,
|
||||
uint32_t stage_idx,
|
||||
@@ -700,6 +781,18 @@ Pass::Status InstBindlessCheckPass::ProcessImpl() {
|
||||
};
|
||||
modified |= InstProcessEntryPointCallTree(pfn);
|
||||
}
|
||||
if (texel_buffer_enabled_) {
|
||||
// Perform texel buffer bounds check on each entry point function in
|
||||
// module. Generate after descriptor bounds and initialization checks.
|
||||
pfn = [this](BasicBlock::iterator ref_inst_itr,
|
||||
UptrVectorIterator<BasicBlock> ref_block_itr,
|
||||
uint32_t stage_idx,
|
||||
std::vector<std::unique_ptr<BasicBlock>>* new_blocks) {
|
||||
return GenTexBuffCheckCode(ref_inst_itr, ref_block_itr, stage_idx,
|
||||
new_blocks);
|
||||
};
|
||||
modified |= InstProcessEntryPointCallTree(pfn);
|
||||
}
|
||||
return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,24 +28,16 @@ namespace opt {
|
||||
// external design may change as the layer evolves.
|
||||
class InstBindlessCheckPass : public InstrumentPass {
|
||||
public:
|
||||
// Old interface to support testing pre-buffer-overrun capability
|
||||
InstBindlessCheckPass(uint32_t desc_set, uint32_t shader_id,
|
||||
bool desc_idx_enable, bool desc_init_enable)
|
||||
: InstrumentPass(desc_set, shader_id, kInstValidationIdBindless, false),
|
||||
desc_idx_enabled_(desc_idx_enable),
|
||||
desc_init_enabled_(desc_init_enable),
|
||||
buffer_bounds_enabled_(false) {}
|
||||
|
||||
// New interface supporting buffer overrun checking
|
||||
InstBindlessCheckPass(uint32_t desc_set, uint32_t shader_id,
|
||||
bool desc_idx_enable, bool desc_init_enable,
|
||||
bool buffer_bounds_enable)
|
||||
: InstrumentPass(
|
||||
desc_set, shader_id, kInstValidationIdBindless,
|
||||
desc_idx_enable || desc_init_enable || buffer_bounds_enable),
|
||||
bool buffer_bounds_enable, bool texel_buffer_enable,
|
||||
bool opt_direct_reads)
|
||||
: InstrumentPass(desc_set, shader_id, kInstValidationIdBindless,
|
||||
opt_direct_reads),
|
||||
desc_idx_enabled_(desc_idx_enable),
|
||||
desc_init_enabled_(desc_init_enable),
|
||||
buffer_bounds_enabled_(buffer_bounds_enable) {}
|
||||
buffer_bounds_enabled_(buffer_bounds_enable),
|
||||
texel_buffer_enabled_(texel_buffer_enable) {}
|
||||
|
||||
~InstBindlessCheckPass() override = default;
|
||||
|
||||
@@ -63,6 +55,10 @@ class InstBindlessCheckPass : public InstrumentPass {
|
||||
// checks that the referenced descriptor has been initialized, if the
|
||||
// SPV_EXT_descriptor_indexing extension is enabled, and initialized large
|
||||
// enough to handle the reference, if RobustBufferAccess is disabled.
|
||||
// GenDescInitCheckCode checks for uniform and storage buffer overrun.
|
||||
// GenTexBuffCheckCode checks for texel buffer overrun and should be
|
||||
// run after GenDescInitCheckCode to first make sure that the descriptor
|
||||
// is initialized because it uses OpImageQuerySize on the descriptor.
|
||||
//
|
||||
// The functions are designed to be passed to
|
||||
// InstrumentPass::InstProcessEntryPointCallTree(), which applies the
|
||||
@@ -109,6 +105,11 @@ class InstBindlessCheckPass : public InstrumentPass {
|
||||
UptrVectorIterator<BasicBlock> ref_block_itr, uint32_t stage_idx,
|
||||
std::vector<std::unique_ptr<BasicBlock>>* new_blocks);
|
||||
|
||||
void GenTexBuffCheckCode(
|
||||
BasicBlock::iterator ref_inst_itr,
|
||||
UptrVectorIterator<BasicBlock> ref_block_itr, uint32_t stage_idx,
|
||||
std::vector<std::unique_ptr<BasicBlock>>* new_blocks);
|
||||
|
||||
// Generate instructions into |builder| to read length of runtime descriptor
|
||||
// array |var_id| from debug input buffer and return id of value.
|
||||
uint32_t GenDebugReadLength(uint32_t var_id, InstructionBuilder* builder);
|
||||
@@ -122,7 +123,7 @@ class InstBindlessCheckPass : public InstrumentPass {
|
||||
// Analysis data for descriptor reference components, generated by
|
||||
// AnalyzeDescriptorReference. It is necessary and sufficient for further
|
||||
// analysis and regeneration of the reference.
|
||||
typedef struct ref_analysis {
|
||||
typedef struct RefAnalysis {
|
||||
uint32_t desc_load_id;
|
||||
uint32_t image_id;
|
||||
uint32_t load_id;
|
||||
@@ -130,7 +131,7 @@ class InstBindlessCheckPass : public InstrumentPass {
|
||||
uint32_t var_id;
|
||||
uint32_t desc_idx_id;
|
||||
Instruction* ref_inst;
|
||||
} ref_analysis;
|
||||
} RefAnalysis;
|
||||
|
||||
// Return size of type |ty_id| in bytes. Use |matrix_stride| and |col_major|
|
||||
// for matrix type, or for vector type if vector is |in_matrix|.
|
||||
@@ -142,11 +143,15 @@ class InstBindlessCheckPass : public InstrumentPass {
|
||||
uint32_t FindStride(uint32_t ty_id, uint32_t stride_deco);
|
||||
|
||||
// Generate index of last byte referenced by buffer reference |ref|
|
||||
uint32_t GenLastByteIdx(ref_analysis* ref, InstructionBuilder* builder);
|
||||
uint32_t GenLastByteIdx(RefAnalysis* ref, InstructionBuilder* builder);
|
||||
|
||||
// Clone original image computation starting at |image_id| into |builder|.
|
||||
// This may generate more than one instruction if neccessary.
|
||||
uint32_t CloneOriginalImage(uint32_t image_id, InstructionBuilder* builder);
|
||||
|
||||
// Clone original original reference encapsulated by |ref| into |builder|.
|
||||
// This may generate more than one instruction if neccessary.
|
||||
uint32_t CloneOriginalReference(ref_analysis* ref,
|
||||
uint32_t CloneOriginalReference(RefAnalysis* ref,
|
||||
InstructionBuilder* builder);
|
||||
|
||||
// If |inst| references through an image, return the id of the image it
|
||||
@@ -158,7 +163,7 @@ class InstBindlessCheckPass : public InstrumentPass {
|
||||
|
||||
// Analyze descriptor reference |ref_inst| and save components into |ref|.
|
||||
// Return true if |ref_inst| is a descriptor reference, false otherwise.
|
||||
bool AnalyzeDescriptorReference(Instruction* ref_inst, ref_analysis* ref);
|
||||
bool AnalyzeDescriptorReference(Instruction* ref_inst, RefAnalysis* ref);
|
||||
|
||||
// Generate instrumentation code for generic test result |check_id|, starting
|
||||
// with |builder| of block |new_blk_ptr|, adding new blocks to |new_blocks|.
|
||||
@@ -168,7 +173,7 @@ class InstBindlessCheckPass : public InstrumentPass {
|
||||
// |stage_idx|. Generate merge block for valid and invalid branches. Kill
|
||||
// original reference.
|
||||
void GenCheckCode(uint32_t check_id, uint32_t error_id, uint32_t offset_id,
|
||||
uint32_t length_id, uint32_t stage_idx, ref_analysis* ref,
|
||||
uint32_t length_id, uint32_t stage_idx, RefAnalysis* ref,
|
||||
std::vector<std::unique_ptr<BasicBlock>>* new_blocks);
|
||||
|
||||
// Initialize state for instrumenting bindless checking
|
||||
@@ -184,9 +189,12 @@ class InstBindlessCheckPass : public InstrumentPass {
|
||||
// Enable instrumentation of descriptor initialization checking
|
||||
bool desc_init_enabled_;
|
||||
|
||||
// Enable instrumentation of buffer overrun checking
|
||||
// Enable instrumentation of uniform and storage buffer overrun checking
|
||||
bool buffer_bounds_enabled_;
|
||||
|
||||
// Enable instrumentation of texel buffer overrun checking
|
||||
bool texel_buffer_enabled_;
|
||||
|
||||
// Mapping from variable to descriptor set
|
||||
std::unordered_map<uint32_t, uint32_t> var2desc_set_;
|
||||
|
||||
|
||||
15
3rdparty/spirv-tools/source/opt/optimizer.cpp
vendored
15
3rdparty/spirv-tools/source/opt/optimizer.cpp
vendored
@@ -425,7 +425,7 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) {
|
||||
RegisterPass(CreateBlockMergePass());
|
||||
RegisterPass(CreateAggressiveDCEPass());
|
||||
} else if (pass_name == "inst-buff-oob-check") {
|
||||
RegisterPass(CreateInstBindlessCheckPass(7, 23, false, false, true));
|
||||
RegisterPass(CreateInstBindlessCheckPass(7, 23, false, false, true, true));
|
||||
RegisterPass(CreateSimplificationPass());
|
||||
RegisterPass(CreateDeadBranchElimPass());
|
||||
RegisterPass(CreateBlockMergePass());
|
||||
@@ -892,15 +892,14 @@ Optimizer::PassToken CreateUpgradeMemoryModelPass() {
|
||||
MakeUnique<opt::UpgradeMemoryModel>());
|
||||
}
|
||||
|
||||
Optimizer::PassToken CreateInstBindlessCheckPass(uint32_t desc_set,
|
||||
uint32_t shader_id,
|
||||
bool input_length_enable,
|
||||
bool input_init_enable,
|
||||
bool input_buff_oob_enable) {
|
||||
Optimizer::PassToken CreateInstBindlessCheckPass(
|
||||
uint32_t desc_set, uint32_t shader_id, bool desc_length_enable,
|
||||
bool desc_init_enable, bool buff_oob_enable, bool texbuff_oob_enable) {
|
||||
return MakeUnique<Optimizer::PassToken::Impl>(
|
||||
MakeUnique<opt::InstBindlessCheckPass>(
|
||||
desc_set, shader_id, input_length_enable, input_init_enable,
|
||||
input_buff_oob_enable));
|
||||
desc_set, shader_id, desc_length_enable, desc_init_enable,
|
||||
buff_oob_enable, texbuff_oob_enable,
|
||||
desc_length_enable || desc_init_enable || buff_oob_enable));
|
||||
}
|
||||
|
||||
Optimizer::PassToken CreateInstDebugPrintfPass(uint32_t desc_set,
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
// Validates correctness of built-in variables.
|
||||
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <map>
|
||||
@@ -134,6 +135,114 @@ bool IsBuiltInValidForWebGPU(SpvBuiltIn label) {
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef enum VUIDError_ {
|
||||
VUIDErrorExecutionModel = 0,
|
||||
VUIDErrorStorageClass = 1,
|
||||
VUIDErrorType = 2,
|
||||
VUIDErrorMax,
|
||||
} VUIDError;
|
||||
|
||||
const static uint32_t NumRtBuiltins = 16;
|
||||
|
||||
typedef struct {
|
||||
SpvBuiltIn builtIn;
|
||||
uint32_t vuid[VUIDErrorMax]; // execution mode, storage class, type VUIDs
|
||||
} RtBuiltinVUIDMapping;
|
||||
|
||||
std::array<RtBuiltinVUIDMapping, NumRtBuiltins> rtBuiltinInfo = {{
|
||||
// clang-format off
|
||||
{SpvBuiltInHitKindKHR, {4242, 4243, 4244}},
|
||||
{SpvBuiltInHitTNV, {4245, 4246, 4247}},
|
||||
{SpvBuiltInInstanceCustomIndexKHR, {4251, 4252, 4253}},
|
||||
{SpvBuiltInInstanceId, {4254, 4255, 4256}},
|
||||
{SpvBuiltInRayGeometryIndexKHR, {4345, 4346, 4347}},
|
||||
{SpvBuiltInObjectRayDirectionKHR, {4299, 4300, 4301}},
|
||||
{SpvBuiltInObjectRayOriginKHR, {4302, 4303, 4304}},
|
||||
{SpvBuiltInObjectToWorldKHR, {4305, 4306, 4307}},
|
||||
{SpvBuiltInWorldToObjectKHR, {4434, 4435, 4436}},
|
||||
{SpvBuiltInIncomingRayFlagsKHR, {4248, 4249, 4250}},
|
||||
{SpvBuiltInRayTminKHR, {4351, 4352, 4353}},
|
||||
{SpvBuiltInRayTmaxKHR, {4348, 4349, 4350}},
|
||||
{SpvBuiltInWorldRayDirectionKHR, {4428, 4429, 4430}},
|
||||
{SpvBuiltInWorldRayOriginKHR, {4431, 4432, 4433}},
|
||||
{SpvBuiltInLaunchIdKHR, {4266, 4267, 4268}},
|
||||
{SpvBuiltInLaunchSizeKHR, {4269, 4270, 4271}},
|
||||
// clang-format off
|
||||
} };
|
||||
|
||||
uint32_t GetVUIDForRTBuiltin(SpvBuiltIn builtIn, VUIDError type) {
|
||||
uint32_t vuid = 0;
|
||||
for (const auto& iter: rtBuiltinInfo) {
|
||||
if (iter.builtIn == builtIn) {
|
||||
assert(type < VUIDErrorMax);
|
||||
vuid = iter.vuid[type];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return vuid;
|
||||
}
|
||||
|
||||
bool IsExecutionModelValidForRtBuiltIn(SpvBuiltIn builtin,
|
||||
SpvExecutionModel stage) {
|
||||
switch (builtin) {
|
||||
case SpvBuiltInHitKindKHR:
|
||||
case SpvBuiltInHitTNV:
|
||||
if (stage == SpvExecutionModelAnyHitKHR ||
|
||||
stage == SpvExecutionModelClosestHitKHR) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SpvBuiltInInstanceCustomIndexKHR:
|
||||
case SpvBuiltInInstanceId:
|
||||
case SpvBuiltInRayGeometryIndexKHR:
|
||||
case SpvBuiltInObjectRayDirectionKHR:
|
||||
case SpvBuiltInObjectRayOriginKHR:
|
||||
case SpvBuiltInObjectToWorldKHR:
|
||||
case SpvBuiltInWorldToObjectKHR:
|
||||
switch (stage) {
|
||||
case SpvExecutionModelIntersectionKHR:
|
||||
case SpvExecutionModelAnyHitKHR:
|
||||
case SpvExecutionModelClosestHitKHR:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case SpvBuiltInIncomingRayFlagsKHR:
|
||||
case SpvBuiltInRayTminKHR:
|
||||
case SpvBuiltInRayTmaxKHR:
|
||||
case SpvBuiltInWorldRayDirectionKHR:
|
||||
case SpvBuiltInWorldRayOriginKHR:
|
||||
switch (stage) {
|
||||
case SpvExecutionModelIntersectionKHR:
|
||||
case SpvExecutionModelAnyHitKHR:
|
||||
case SpvExecutionModelClosestHitKHR:
|
||||
case SpvExecutionModelMissKHR:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case SpvBuiltInLaunchIdKHR:
|
||||
case SpvBuiltInLaunchSizeKHR:
|
||||
switch (stage) {
|
||||
case SpvExecutionModelRayGenerationKHR:
|
||||
case SpvExecutionModelIntersectionKHR:
|
||||
case SpvExecutionModelAnyHitKHR:
|
||||
case SpvExecutionModelClosestHitKHR:
|
||||
case SpvExecutionModelMissKHR:
|
||||
case SpvExecutionModelCallableKHR:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Helper class managing validation of built-ins.
|
||||
// TODO: Generic functionality of this class can be moved into
|
||||
// ValidationState_t to be made available to other users.
|
||||
@@ -200,8 +309,8 @@ class BuiltInsValidator {
|
||||
const Instruction& inst);
|
||||
spv_result_t ValidateVertexIndexAtDefinition(const Decoration& decoration,
|
||||
const Instruction& inst);
|
||||
spv_result_t ValidateVertexIdOrInstanceIdAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst);
|
||||
spv_result_t ValidateVertexIdAtDefinition(const Decoration& decoration,
|
||||
const Instruction& inst);
|
||||
spv_result_t ValidateLocalInvocationIndexAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst);
|
||||
spv_result_t ValidateWorkgroupSizeAtDefinition(const Decoration& decoration,
|
||||
@@ -237,6 +346,9 @@ class BuiltInsValidator {
|
||||
spv_result_t ValidateShadingRateAtDefinition(const Decoration& decoration,
|
||||
const Instruction& inst);
|
||||
|
||||
spv_result_t ValidateRayTracingBuiltinsAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst);
|
||||
|
||||
// The following section contains functions which are called when id defined
|
||||
// by |referenced_inst| is
|
||||
// 1. referenced by |referenced_from_inst|
|
||||
@@ -269,11 +381,6 @@ class BuiltInsValidator {
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst);
|
||||
|
||||
spv_result_t ValidateInstanceIdAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst);
|
||||
|
||||
spv_result_t ValidateInstanceIndexAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
@@ -400,6 +507,11 @@ class BuiltInsValidator {
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst);
|
||||
|
||||
spv_result_t ValidateRayTracingBuiltinsAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst);
|
||||
|
||||
// Validates that |built_in_inst| is not (even indirectly) referenced from
|
||||
// within a function which can be called with |execution_model|.
|
||||
//
|
||||
@@ -476,6 +588,10 @@ class BuiltInsValidator {
|
||||
uint32_t num_components,
|
||||
const std::function<spv_result_t(const std::string& message)>& diag,
|
||||
uint32_t underlying_type);
|
||||
spv_result_t ValidateF32Mat(
|
||||
const Decoration& decoration, const Instruction& inst,
|
||||
uint32_t req_num_rows, uint32_t req_num_columns,
|
||||
const std::function<spv_result_t(const std::string& message)>& diag);
|
||||
|
||||
// Generates strings like "Member #0 of struct ID <2>".
|
||||
std::string GetDefinitionDesc(const Decoration& decoration,
|
||||
@@ -909,6 +1025,32 @@ spv_result_t BuiltInsValidator::ValidateF32ArrHelper(
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidateF32Mat(
|
||||
const Decoration& decoration, const Instruction& inst,
|
||||
uint32_t req_num_rows, uint32_t req_num_columns,
|
||||
const std::function<spv_result_t(const std::string& message)>& diag) {
|
||||
uint32_t underlying_type = 0;
|
||||
uint32_t num_rows = 0;
|
||||
uint32_t num_cols = 0;
|
||||
uint32_t col_type = 0;
|
||||
uint32_t component_type = 0;
|
||||
if (spv_result_t error =
|
||||
GetUnderlyingType(_, decoration, inst, &underlying_type)) {
|
||||
return error;
|
||||
}
|
||||
if (!_.GetMatrixTypeInfo(underlying_type, &num_rows, &num_cols, &col_type,
|
||||
&component_type) ||
|
||||
num_rows != req_num_rows || num_cols != req_num_columns) {
|
||||
std::ostringstream ss;
|
||||
ss << GetDefinitionDesc(decoration, inst) << " has columns " << num_cols
|
||||
<< " and rows " << num_rows << " not equal to expected "
|
||||
<< req_num_columns << "x" << req_num_rows << ".";
|
||||
return diag(ss.str());
|
||||
}
|
||||
|
||||
return ValidateF32VecHelper(decoration, inst, req_num_rows, diag, col_type);
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidateNotCalledWithExecutionModel(
|
||||
int vuid, const char* comment, SpvExecutionModel execution_model,
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
@@ -1947,6 +2089,27 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveIdAtReference(
|
||||
"Fragment.",
|
||||
SpvExecutionModelFragment, decoration, built_in_inst,
|
||||
referenced_from_inst, std::placeholders::_1));
|
||||
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
|
||||
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334,
|
||||
"Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for "
|
||||
"variables with Output storage class if execution model is "
|
||||
"IntersectionKHR.",
|
||||
SpvExecutionModelIntersectionKHR, decoration, built_in_inst,
|
||||
referenced_from_inst, std::placeholders::_1));
|
||||
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
|
||||
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334,
|
||||
"Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for "
|
||||
"variables with Output storage class if execution model is "
|
||||
"AnyHitKHR.",
|
||||
SpvExecutionModelAnyHitKHR, decoration, built_in_inst,
|
||||
referenced_from_inst, std::placeholders::_1));
|
||||
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
|
||||
&BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4334,
|
||||
"Vulkan spec doesn't allow BuiltIn PrimitiveId to be used for "
|
||||
"variables with Output storage class if execution model is "
|
||||
"ClosestHitKHR.",
|
||||
SpvExecutionModelClosestHitKHR, decoration, built_in_inst,
|
||||
referenced_from_inst, std::placeholders::_1));
|
||||
}
|
||||
|
||||
for (const SpvExecutionModel execution_model : execution_models_) {
|
||||
@@ -1956,12 +2119,9 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveIdAtReference(
|
||||
case SpvExecutionModelTessellationEvaluation:
|
||||
case SpvExecutionModelGeometry:
|
||||
case SpvExecutionModelMeshNV:
|
||||
case SpvExecutionModelRayGenerationNV:
|
||||
case SpvExecutionModelIntersectionNV:
|
||||
case SpvExecutionModelAnyHitNV:
|
||||
case SpvExecutionModelClosestHitNV:
|
||||
case SpvExecutionModelMissNV:
|
||||
case SpvExecutionModelCallableNV: {
|
||||
case SpvExecutionModelIntersectionKHR:
|
||||
case SpvExecutionModelAnyHitKHR:
|
||||
case SpvExecutionModelClosestHitKHR: {
|
||||
// Ok.
|
||||
break;
|
||||
}
|
||||
@@ -1971,7 +2131,9 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveIdAtReference(
|
||||
<< _.VkErrorID(4330)
|
||||
<< "Vulkan spec allows BuiltIn PrimitiveId to be used only "
|
||||
"with Fragment, TessellationControl, "
|
||||
"TessellationEvaluation or Geometry execution models. "
|
||||
"TessellationEvaluation, Geometry, MeshNV, "
|
||||
"IntersectionKHR, "
|
||||
"AnyHitKHR, and ClosestHitKHR execution models. "
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
referenced_from_inst, execution_model);
|
||||
}
|
||||
@@ -2372,54 +2534,13 @@ spv_result_t BuiltInsValidator::ValidateVertexIndexAtDefinition(
|
||||
return ValidateVertexIndexAtReference(decoration, inst, inst, inst);
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidateVertexIdOrInstanceIdAtDefinition(
|
||||
spv_result_t BuiltInsValidator::ValidateVertexIdAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
const SpvBuiltIn label = SpvBuiltIn(decoration.params()[0]);
|
||||
bool allow_instance_id = (_.HasCapability(SpvCapabilityRayTracingNV) ||
|
||||
_.HasCapability(SpvCapabilityRayTracingKHR)) &&
|
||||
label == SpvBuiltInInstanceId;
|
||||
|
||||
if (spvIsVulkanEnv(_.context()->target_env) && !allow_instance_id) {
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< "Vulkan spec doesn't allow BuiltIn VertexId/InstanceId "
|
||||
"to be used.";
|
||||
}
|
||||
|
||||
if (label == SpvBuiltInInstanceId) {
|
||||
return ValidateInstanceIdAtReference(decoration, inst, inst, inst);
|
||||
}
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidateInstanceIdAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst) {
|
||||
(void)decoration;
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
for (const SpvExecutionModel execution_model : execution_models_) {
|
||||
switch (execution_model) {
|
||||
case SpvExecutionModelIntersectionNV:
|
||||
case SpvExecutionModelClosestHitNV:
|
||||
case SpvExecutionModelAnyHitNV:
|
||||
// Do nothing, valid stages
|
||||
break;
|
||||
default:
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< "Vulkan spec allows BuiltIn InstanceId to be used "
|
||||
"only with IntersectionNV, ClosestHitNV and AnyHitNV "
|
||||
"execution models. "
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
referenced_from_inst);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (function_id_ == 0) {
|
||||
// Propagate this rule to all dependant ids in the global scope.
|
||||
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
|
||||
&BuiltInsValidator::ValidateInstanceIdAtReference, this, decoration,
|
||||
built_in_inst, referenced_from_inst, std::placeholders::_1));
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< "Vulkan spec doesn't allow BuiltIn VertexId "
|
||||
"to be used.";
|
||||
}
|
||||
|
||||
return SPV_SUCCESS;
|
||||
@@ -3474,6 +3595,174 @@ spv_result_t BuiltInsValidator::ValidateShadingRateAtReference(
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
|
||||
switch (builtin) {
|
||||
case SpvBuiltInHitTNV:
|
||||
case SpvBuiltInRayTminKHR:
|
||||
case SpvBuiltInRayTmaxKHR:
|
||||
// f32 scalar
|
||||
if (spv_result_t error = ValidateF32(
|
||||
decoration, inst,
|
||||
[this, &inst,
|
||||
builtin](const std::string& message) -> spv_result_t {
|
||||
uint32_t vuid = GetVUIDForRTBuiltin(builtin, VUIDErrorType);
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< _.VkErrorID(vuid)
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN, builtin)
|
||||
<< " variable needs to be a 32-bit float scalar. "
|
||||
<< message;
|
||||
})) {
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
case SpvBuiltInHitKindKHR:
|
||||
case SpvBuiltInInstanceCustomIndexKHR:
|
||||
case SpvBuiltInInstanceId:
|
||||
case SpvBuiltInRayGeometryIndexKHR:
|
||||
case SpvBuiltInIncomingRayFlagsKHR:
|
||||
// i32 scalar
|
||||
if (spv_result_t error = ValidateI32(
|
||||
decoration, inst,
|
||||
[this, &inst,
|
||||
builtin](const std::string& message) -> spv_result_t {
|
||||
uint32_t vuid = GetVUIDForRTBuiltin(builtin, VUIDErrorType);
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< _.VkErrorID(vuid)
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN, builtin)
|
||||
<< " variable needs to be a 32-bit int scalar. "
|
||||
<< message;
|
||||
})) {
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
case SpvBuiltInObjectRayDirectionKHR:
|
||||
case SpvBuiltInObjectRayOriginKHR:
|
||||
case SpvBuiltInWorldRayDirectionKHR:
|
||||
case SpvBuiltInWorldRayOriginKHR:
|
||||
// f32 vec3
|
||||
if (spv_result_t error = ValidateF32Vec(
|
||||
decoration, inst, 3,
|
||||
[this, &inst,
|
||||
builtin](const std::string& message) -> spv_result_t {
|
||||
uint32_t vuid = GetVUIDForRTBuiltin(builtin, VUIDErrorType);
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< _.VkErrorID(vuid)
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN, builtin)
|
||||
<< " variable needs to be a 3-component 32-bit float "
|
||||
"vector. "
|
||||
<< message;
|
||||
})) {
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
case SpvBuiltInLaunchIdKHR:
|
||||
case SpvBuiltInLaunchSizeKHR:
|
||||
// i32 vec3
|
||||
if (spv_result_t error = ValidateI32Vec(
|
||||
decoration, inst, 3,
|
||||
[this, &inst,
|
||||
builtin](const std::string& message) -> spv_result_t {
|
||||
uint32_t vuid = GetVUIDForRTBuiltin(builtin, VUIDErrorType);
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< _.VkErrorID(vuid)
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN, builtin)
|
||||
<< " variable needs to be a 3-component 32-bit int "
|
||||
"vector. "
|
||||
<< message;
|
||||
})) {
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
case SpvBuiltInObjectToWorldKHR:
|
||||
case SpvBuiltInWorldToObjectKHR:
|
||||
// f32 mat4x3
|
||||
if (spv_result_t error = ValidateF32Mat(
|
||||
decoration, inst, 3, 4,
|
||||
[this, &inst,
|
||||
builtin](const std::string& message) -> spv_result_t {
|
||||
uint32_t vuid = GetVUIDForRTBuiltin(builtin, VUIDErrorType);
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &inst)
|
||||
<< _.VkErrorID(vuid)
|
||||
<< "According to the Vulkan spec BuiltIn "
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_BUILT_IN, builtin)
|
||||
<< " variable needs to be a matrix with"
|
||||
<< " 4 columns of 3-component vectors of 32-bit "
|
||||
"floats. "
|
||||
<< message;
|
||||
})) {
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Unexpected ray tracing builtin");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Seed at reference checks with this built-in.
|
||||
return ValidateRayTracingBuiltinsAtReference(decoration, inst, inst, inst);
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference(
|
||||
const Decoration& decoration, const Instruction& built_in_inst,
|
||||
const Instruction& referenced_inst,
|
||||
const Instruction& referenced_from_inst) {
|
||||
if (spvIsVulkanEnv(_.context()->target_env)) {
|
||||
const SpvBuiltIn builtin = SpvBuiltIn(decoration.params()[0]);
|
||||
const SpvStorageClass storage_class = GetStorageClass(referenced_from_inst);
|
||||
if (storage_class != SpvStorageClassMax &&
|
||||
storage_class != SpvStorageClassInput) {
|
||||
uint32_t vuid = GetVUIDForRTBuiltin(builtin, VUIDErrorStorageClass);
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " to be only used for variables with Input storage class. "
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
referenced_from_inst)
|
||||
<< " " << GetStorageClassDesc(referenced_from_inst);
|
||||
}
|
||||
|
||||
for (const SpvExecutionModel execution_model : execution_models_) {
|
||||
if (!IsExecutionModelValidForRtBuiltIn(builtin, execution_model)) {
|
||||
uint32_t vuid = GetVUIDForRTBuiltin(builtin, VUIDErrorExecutionModel);
|
||||
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
|
||||
<< _.VkErrorID(vuid) << "Vulkan spec does not allow BuiltIn "
|
||||
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
|
||||
decoration.params()[0])
|
||||
<< " to be used with the execution model "
|
||||
<< _.grammar().lookupOperandName(
|
||||
SPV_OPERAND_TYPE_EXECUTION_MODEL, execution_model)
|
||||
<< ".\n"
|
||||
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
|
||||
referenced_from_inst, execution_model);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (function_id_ == 0) {
|
||||
// Propagate this rule to all dependant ids in the global scope.
|
||||
id_to_at_reference_checks_[referenced_from_inst.id()].push_back(
|
||||
std::bind(&BuiltInsValidator::ValidateRayTracingBuiltinsAtReference,
|
||||
this, decoration, built_in_inst, referenced_from_inst,
|
||||
std::placeholders::_1));
|
||||
}
|
||||
|
||||
return SPV_SUCCESS;
|
||||
}
|
||||
|
||||
spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
|
||||
const Decoration& decoration, const Instruction& inst) {
|
||||
const SpvBuiltIn label = SpvBuiltIn(decoration.params()[0]);
|
||||
@@ -3596,9 +3885,8 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
|
||||
case SpvBuiltInWorkgroupSize: {
|
||||
return ValidateWorkgroupSizeAtDefinition(decoration, inst);
|
||||
}
|
||||
case SpvBuiltInVertexId:
|
||||
case SpvBuiltInInstanceId: {
|
||||
return ValidateVertexIdOrInstanceIdAtDefinition(decoration, inst);
|
||||
case SpvBuiltInVertexId: {
|
||||
return ValidateVertexIdAtDefinition(decoration, inst);
|
||||
}
|
||||
case SpvBuiltInLocalInvocationIndex: {
|
||||
return ValidateLocalInvocationIndexAtDefinition(decoration, inst);
|
||||
@@ -3622,6 +3910,27 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
|
||||
case SpvBuiltInDeviceIndex: {
|
||||
return ValidateDeviceIndexAtDefinition(decoration, inst);
|
||||
}
|
||||
// Ray tracing builtins
|
||||
case SpvBuiltInHitKindKHR: // alias SpvBuiltInHitKindNV
|
||||
case SpvBuiltInHitTNV: // NOT present in KHR
|
||||
case SpvBuiltInInstanceId:
|
||||
case SpvBuiltInLaunchIdKHR: // alias SpvBuiltInLaunchIdNV
|
||||
case SpvBuiltInLaunchSizeKHR: // alias SpvBuiltInLaunchSizeNV
|
||||
case SpvBuiltInWorldRayOriginKHR: // alias SpvBuiltInWorldRayOriginNV
|
||||
case SpvBuiltInWorldRayDirectionKHR: // alias SpvBuiltInWorldRayDirectionNV
|
||||
case SpvBuiltInObjectRayOriginKHR: // alias SpvBuiltInObjectRayOriginNV
|
||||
case SpvBuiltInObjectRayDirectionKHR: // alias
|
||||
// SpvBuiltInObjectRayDirectionNV
|
||||
case SpvBuiltInRayTminKHR: // alias SpvBuiltInRayTminNV
|
||||
case SpvBuiltInRayTmaxKHR: // alias SpvBuiltInRayTmaxNV
|
||||
case SpvBuiltInInstanceCustomIndexKHR: // alias
|
||||
// SpvBuiltInInstanceCustomIndexNV
|
||||
case SpvBuiltInObjectToWorldKHR: // alias SpvBuiltInObjectToWorldNV
|
||||
case SpvBuiltInWorldToObjectKHR: // alias SpvBuiltInWorldToObjectNV
|
||||
case SpvBuiltInIncomingRayFlagsKHR: // alias SpvBuiltInIncomingRayFlagsNV
|
||||
case SpvBuiltInRayGeometryIndexKHR: { // NOT present in NV
|
||||
return ValidateRayTracingBuiltinsAtDefinition(decoration, inst);
|
||||
}
|
||||
case SpvBuiltInWorkDim:
|
||||
case SpvBuiltInGlobalSize:
|
||||
case SpvBuiltInEnqueuedWorkgroupSize:
|
||||
@@ -3657,28 +3966,14 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
|
||||
case SpvBuiltInFragmentSizeNV: // alias SpvBuiltInFragSizeEXT
|
||||
case SpvBuiltInInvocationsPerPixelNV: // alias
|
||||
// SpvBuiltInFragInvocationCountEXT
|
||||
case SpvBuiltInLaunchIdNV:
|
||||
case SpvBuiltInLaunchSizeNV:
|
||||
case SpvBuiltInWorldRayOriginNV:
|
||||
case SpvBuiltInWorldRayDirectionNV:
|
||||
case SpvBuiltInObjectRayOriginNV:
|
||||
case SpvBuiltInObjectRayDirectionNV:
|
||||
case SpvBuiltInRayTminNV:
|
||||
case SpvBuiltInRayTmaxNV:
|
||||
case SpvBuiltInInstanceCustomIndexNV:
|
||||
case SpvBuiltInObjectToWorldNV:
|
||||
case SpvBuiltInWorldToObjectNV:
|
||||
case SpvBuiltInHitTNV:
|
||||
case SpvBuiltInHitKindNV:
|
||||
case SpvBuiltInIncomingRayFlagsNV:
|
||||
case SpvBuiltInRayGeometryIndexKHR: {
|
||||
// No validation rules (for the moment).
|
||||
break;
|
||||
|
||||
case SpvBuiltInPrimitiveShadingRateKHR:
|
||||
return ValidatePrimitiveShadingRateAtDefinition(decoration, inst);
|
||||
case SpvBuiltInShadingRateKHR:
|
||||
return ValidateShadingRateAtDefinition(decoration, inst);
|
||||
case SpvBuiltInPrimitiveShadingRateKHR: {
|
||||
return ValidatePrimitiveShadingRateAtDefinition(decoration, inst);
|
||||
}
|
||||
case SpvBuiltInShadingRateKHR: {
|
||||
return ValidateShadingRateAtDefinition(decoration, inst);
|
||||
}
|
||||
}
|
||||
return SPV_SUCCESS;
|
||||
|
||||
@@ -1363,6 +1363,36 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
|
||||
return VUID_WRAP(VUID-HelperInvocation-HelperInvocation-04240);
|
||||
case 4241:
|
||||
return VUID_WRAP(VUID-HelperInvocation-HelperInvocation-04241);
|
||||
case 4242:
|
||||
return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04242);
|
||||
case 4243:
|
||||
return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04243);
|
||||
case 4244:
|
||||
return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04244);
|
||||
case 4245:
|
||||
return VUID_WRAP(VUID-HitTNV-HitTNV-04245);
|
||||
case 4246:
|
||||
return VUID_WRAP(VUID-HitTNV-HitTNV-04246);
|
||||
case 4247:
|
||||
return VUID_WRAP(VUID-HitTNV-HitTNV-04247);
|
||||
case 4248:
|
||||
return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04248);
|
||||
case 4249:
|
||||
return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04249);
|
||||
case 4250:
|
||||
return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04250);
|
||||
case 4251:
|
||||
return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04251);
|
||||
case 4252:
|
||||
return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04252);
|
||||
case 4253:
|
||||
return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04253);
|
||||
case 4254:
|
||||
return VUID_WRAP(VUID-InstanceId-InstanceId-04254);
|
||||
case 4255:
|
||||
return VUID_WRAP(VUID-InstanceId-InstanceId-04255);
|
||||
case 4256:
|
||||
return VUID_WRAP(VUID-InstanceId-InstanceId-04256);
|
||||
case 4257:
|
||||
return VUID_WRAP(VUID-InvocationId-InvocationId-04257);
|
||||
case 4258:
|
||||
@@ -1375,6 +1405,18 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
|
||||
return VUID_WRAP(VUID-InstanceIndex-InstanceIndex-04264);
|
||||
case 4265:
|
||||
return VUID_WRAP(VUID-InstanceIndex-InstanceIndex-04265);
|
||||
case 4266:
|
||||
return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04266);
|
||||
case 4267:
|
||||
return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04267);
|
||||
case 4268:
|
||||
return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04268);
|
||||
case 4269:
|
||||
return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04269);
|
||||
case 4270:
|
||||
return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04270);
|
||||
case 4271:
|
||||
return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04271);
|
||||
case 4272:
|
||||
return VUID_WRAP(VUID-Layer-Layer-04272);
|
||||
case 4274:
|
||||
@@ -1395,6 +1437,24 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
|
||||
return VUID_WRAP(VUID-NumWorkgroups-NumWorkgroups-04297);
|
||||
case 4298:
|
||||
return VUID_WRAP(VUID-NumWorkgroups-NumWorkgroups-04298);
|
||||
case 4299:
|
||||
return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04299);
|
||||
case 4300:
|
||||
return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04300);
|
||||
case 4301:
|
||||
return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04301);
|
||||
case 4302:
|
||||
return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04302);
|
||||
case 4303:
|
||||
return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04303);
|
||||
case 4304:
|
||||
return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04304);
|
||||
case 4305:
|
||||
return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04305);
|
||||
case 4306:
|
||||
return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04306);
|
||||
case 4307:
|
||||
return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04307);
|
||||
case 4308:
|
||||
return VUID_WRAP(VUID-PatchVertices-PatchVertices-04308);
|
||||
case 4309:
|
||||
@@ -1427,6 +1487,24 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
|
||||
return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04334);
|
||||
case 4337:
|
||||
return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04337);
|
||||
case 4345:
|
||||
return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04345);
|
||||
case 4346:
|
||||
return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04346);
|
||||
case 4347:
|
||||
return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04347);
|
||||
case 4348:
|
||||
return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04348);
|
||||
case 4349:
|
||||
return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04349);
|
||||
case 4350:
|
||||
return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04350);
|
||||
case 4351:
|
||||
return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04351);
|
||||
case 4352:
|
||||
return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04352);
|
||||
case 4353:
|
||||
return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04353);
|
||||
case 4354:
|
||||
return VUID_WRAP(VUID-SampleId-SampleId-04354);
|
||||
case 4355:
|
||||
@@ -1491,6 +1569,24 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
|
||||
return VUID_WRAP(VUID-WorkgroupSize-WorkgroupSize-04426);
|
||||
case 4427:
|
||||
return VUID_WRAP(VUID-WorkgroupSize-WorkgroupSize-04427);
|
||||
case 4428:
|
||||
return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04428);
|
||||
case 4429:
|
||||
return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04429);
|
||||
case 4430:
|
||||
return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04430);
|
||||
case 4431:
|
||||
return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04431);
|
||||
case 4432:
|
||||
return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04432);
|
||||
case 4433:
|
||||
return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04433);
|
||||
case 4434:
|
||||
return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04434);
|
||||
case 4435:
|
||||
return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04435);
|
||||
case 4436:
|
||||
return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04436);
|
||||
case 4484:
|
||||
return VUID_WRAP(VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04484);
|
||||
case 4485:
|
||||
|
||||
Reference in New Issue
Block a user