summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp')
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp60
1 files changed, 58 insertions, 2 deletions
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp
index 06acc7ea559..e2336d3601d 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp
@@ -130,13 +130,48 @@ void InstBuffAddrCheckPass::GenCheckCode(
context()->KillInst(ref_inst);
}
+uint32_t InstBuffAddrCheckPass::GetTypeAlignment(uint32_t type_id) {
+ Instruction* type_inst = get_def_use_mgr()->GetDef(type_id);
+ switch (type_inst->opcode()) {
+ case SpvOpTypeFloat:
+ case SpvOpTypeInt:
+ case SpvOpTypeVector:
+ return GetTypeLength(type_id);
+ case SpvOpTypeMatrix:
+ return GetTypeAlignment(type_inst->GetSingleWordInOperand(0));
+ case SpvOpTypeArray:
+ case SpvOpTypeRuntimeArray:
+ return GetTypeAlignment(type_inst->GetSingleWordInOperand(0));
+ case SpvOpTypeStruct: {
+ uint32_t max = 0;
+ type_inst->ForEachInId([&max, this](const uint32_t* iid) {
+ uint32_t alignment = GetTypeAlignment(*iid);
+ max = (alignment > max) ? alignment : max;
+ });
+ return max;
+ }
+ case SpvOpTypePointer:
+ assert(type_inst->GetSingleWordInOperand(0) ==
+ SpvStorageClassPhysicalStorageBufferEXT &&
+ "unexpected pointer type");
+ return 8u;
+ default:
+ assert(false && "unexpected type");
+ return 0;
+ }
+}
+
uint32_t InstBuffAddrCheckPass::GetTypeLength(uint32_t type_id) {
Instruction* type_inst = get_def_use_mgr()->GetDef(type_id);
switch (type_inst->opcode()) {
case SpvOpTypeFloat:
case SpvOpTypeInt:
return type_inst->GetSingleWordInOperand(0) / 8u;
- case SpvOpTypeVector:
+ case SpvOpTypeVector: {
+ uint32_t raw_cnt = type_inst->GetSingleWordInOperand(1);
+ uint32_t adj_cnt = (raw_cnt == 3u) ? 4u : raw_cnt;
+ return adj_cnt * GetTypeLength(type_inst->GetSingleWordInOperand(0));
+ }
case SpvOpTypeMatrix:
return type_inst->GetSingleWordInOperand(1) *
GetTypeLength(type_inst->GetSingleWordInOperand(0));
@@ -145,8 +180,29 @@ uint32_t InstBuffAddrCheckPass::GetTypeLength(uint32_t type_id) {
SpvStorageClassPhysicalStorageBufferEXT &&
"unexpected pointer type");
return 8u;
+ case SpvOpTypeArray: {
+ uint32_t const_id = type_inst->GetSingleWordInOperand(1);
+ Instruction* const_inst = get_def_use_mgr()->GetDef(const_id);
+ uint32_t cnt = const_inst->GetSingleWordInOperand(0);
+ return cnt * GetTypeLength(type_inst->GetSingleWordInOperand(0));
+ }
+ case SpvOpTypeStruct: {
+ uint32_t len = 0;
+ type_inst->ForEachInId([&len, this](const uint32_t* iid) {
+ // Align struct length
+ uint32_t alignment = GetTypeAlignment(*iid);
+ uint32_t mod = len % alignment;
+ uint32_t diff = (mod != 0) ? alignment - mod : 0;
+ len += diff;
+ // Increment struct length by component length
+ uint32_t comp_len = GetTypeLength(*iid);
+ len += comp_len;
+ });
+ return len;
+ }
+ case SpvOpTypeRuntimeArray:
default:
- assert(false && "unexpected buffer reference type");
+ assert(false && "unexpected type");
return 0;
}
}