diff --git a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp index 94c9f0bbe..b766e94bf 100644 --- a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp @@ -992,23 +992,44 @@ rdcstr Reflector::Disassemble(const rdcstr &entryPoint, cfgStack.back().mergeTarget == decoded.targetLabel) continue; - // if we're in a switch, branches to the merge block are printed as 'break' - if(!cfgStack.empty() && cfgStack.back().type == StructuredCFG::Switch && - cfgStack.back().mergeTarget == decoded.targetLabel) + const StructuredCFG *lastLoopSwitch = NULL; + + // walk stack to get the last switch/loop that we're in + for(size_t s = 0; s < cfgStack.size(); s++) + { + const StructuredCFG &cfg = cfgStack[cfgStack.size() - 1 - s]; + if(cfg.type == StructuredCFG::Switch || cfg.type == StructuredCFG::Loop) + { + lastLoopSwitch = &cfg; + break; + } + } + + // if we're in a switch/loop, branches to the merge block are printed as 'break' + if(lastLoopSwitch && lastLoopSwitch->mergeTarget == decoded.targetLabel) { ret += indent + "break;\n"; lineNum++; continue; } + // if we're in a loop, branches to the continue target are printed as 'continue' + if(lastLoopSwitch && lastLoopSwitch->type == StructuredCFG::Loop && + lastLoopSwitch->continueTarget == decoded.targetLabel) + { + ret += indent + "continue;\n"; + lineNum++; + continue; + } + // if we're in a switch and we're about to print a goto, see if it's a case label and // print a 'nicer' goto. Fallthrough to the next case would be handled above as a // redundant goto - if(!cfgStack.empty() && cfgStack.back().type == StructuredCFG::Switch) + if(lastLoopSwitch && lastLoopSwitch->type == StructuredCFG::Switch) { bool printed = false; - for(const PairLiteralIntegerIdRef &caseTarget : cfgStack.back().caseTargets) + for(const PairLiteralIntegerIdRef &caseTarget : lastLoopSwitch->caseTargets) { if(caseTarget.second == decoded.targetLabel) { diff --git a/util/test/demos/vk/vk_shader_debug_zoo.cpp b/util/test/demos/vk/vk_shader_debug_zoo.cpp index f4464b901..dfc80f334 100644 --- a/util/test/demos/vk/vk_shader_debug_zoo.cpp +++ b/util/test/demos/vk/vk_shader_debug_zoo.cpp @@ -1452,6 +1452,52 @@ void main() Color = vec4(float(old & 0xfffff), float(imageLoad(atomicimg, ivec2(gl_FragCoord)).x & 0xfffff), 0.0f, 0.0f); break; } + case 171: + { + vec4 ret = vec4(0,0,0,0); + // test loop continues + for(int i=0; i < flatLocalCoord + 5; i++) + { + ret.x += 0.1f; + if(i == 2) + { + ret.y += 0.2f; + continue; + } + ret.z += 0.1f; + if(i == 4) + { + continue; + } + ret.w += 0.1f; + } + Color = ret; + break; + } + case 172: + { + vec4 ret = vec4(0,0,0,0); + // test loop breaks + for(int i=0; i < flatLocalCoord + 5; i++) + { + ret.x += 0.1f; + if(i == 2) + { + break; + } + ret.y += 0.2f; + } + Color = ret; + break; + } + // test fall through + case 173: + Color += vec4(0.5, 0.5, 0.5, 0.5); + case 174: + { + Color += vec4(1.0, 1.0, 1.0, 1.0); + break; + } default: break; } }