| 547 | } |
| 548 | |
| 549 | void ShaderViewer::debugShader(const ShaderReflection *shader, ResourceId pipeline, |
| 550 | ShaderDebugTrace *trace, const QString &debugContext) |
| 551 | { |
| 552 | m_ShaderDetails = shader; |
| 553 | m_Pipeline = pipeline; |
| 554 | m_Trace = trace; |
| 555 | m_Stage = ShaderStage::Vertex; |
| 556 | m_DebugContext = debugContext; |
| 557 | |
| 558 | // no recompilation happening, hide that group |
| 559 | ui->compilationGroup->hide(); |
| 560 | |
| 561 | // no replacing allowed, stay in find mode |
| 562 | m_FindReplace->allowUserModeChange(false); |
| 563 | |
| 564 | if(!m_ShaderDetails) |
| 565 | m_Trace = NULL; |
| 566 | |
| 567 | if(m_ShaderDetails) |
| 568 | { |
| 569 | m_Stage = m_ShaderDetails->stage; |
| 570 | |
| 571 | QPointer<ShaderViewer> me(this); |
| 572 | |
| 573 | m_Ctx.Replay().AsyncInvoke([me, this](IReplayController *r) { |
| 574 | if(!me) |
| 575 | return; |
| 576 | |
| 577 | rdcarray<rdcstr> targets = r->GetDisassemblyTargets(m_Pipeline != ResourceId()); |
| 578 | |
| 579 | if(m_Pipeline == ResourceId()) |
| 580 | { |
| 581 | rdcarray<rdcstr> pipelineTargets = r->GetDisassemblyTargets(true); |
| 582 | |
| 583 | if(pipelineTargets.size() > targets.size()) |
| 584 | { |
| 585 | m_PipelineTargets = pipelineTargets; |
| 586 | m_PipelineTargets.removeIf([&targets](const rdcstr &t) { return targets.contains(t); }); |
| 587 | } |
| 588 | } |
| 589 | |
| 590 | rdcstr disasm = r->DisassembleShader(m_Pipeline, m_ShaderDetails, ""); |
| 591 | |
| 592 | if(!me) |
| 593 | return; |
| 594 | |
| 595 | GUIInvoke::call(this, [this, targets, disasm]() { |
| 596 | QStringList targetNames; |
| 597 | for(int i = 0; i < targets.count(); i++) |
| 598 | { |
| 599 | QString target = targets[i]; |
| 600 | targetNames << QString(targets[i]); |
| 601 | |
| 602 | if(i == 0) |
| 603 | { |
| 604 | // add any custom decompiling tools we have after the first one |
| 605 | for(const ShaderProcessingTool &d : m_Ctx.Config().ShaderProcessors) |
| 606 | { |
no test coverage detected