ShaderCache: Better fix for Shuffling gl_FragCoord

This commit is contained in:
Fernando Sahmkow 2021-10-30 01:47:18 +02:00
parent d46a71e786
commit 6f98690963
1 changed files with 13 additions and 2 deletions

View File

@ -30,7 +30,7 @@ namespace {
return false; return false;
} }
void VisitMark(const IR::Inst& inst) { void VisitMark(IR::Block& block, IR::Inst& inst) {
switch (inst.GetOpcode()) { switch (inst.GetOpcode()) {
case IR::Opcode::ShuffleIndex: case IR::Opcode::ShuffleIndex:
case IR::Opcode::ShuffleUp: case IR::Opcode::ShuffleUp:
@ -49,19 +49,30 @@ void VisitMark(const IR::Inst& inst) {
break; break;
} }
IR::Inst* const bitcast_inst{bitcast_arg.InstRecursive()}; IR::Inst* const bitcast_inst{bitcast_arg.InstRecursive()};
bool must_patch_outside = false;
if (bitcast_inst->GetOpcode() == IR::Opcode::GetAttribute) { if (bitcast_inst->GetOpcode() == IR::Opcode::GetAttribute) {
const IR::Attribute attr{bitcast_inst->Arg(0).Attribute()}; const IR::Attribute attr{bitcast_inst->Arg(0).Attribute()};
switch (attr) { switch (attr) {
case IR::Attribute::PositionX: case IR::Attribute::PositionX:
case IR::Attribute::PositionY: case IR::Attribute::PositionY:
bitcast_inst->SetFlags<u32>(0xDEADBEEF); bitcast_inst->SetFlags<u32>(0xDEADBEEF);
must_patch_outside = true;
break; break;
default: default:
break; break;
} }
} }
if (must_patch_outside) {
const auto it{IR::Block::InstructionList::s_iterator_to(inst)};
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
const IR::F32 new_inst{&*block.PrependNewInst(it, inst)};
const IR::F32 up_factor{ir.FPRecip(ir.ResolutionDownFactor())};
const IR::Value converted{ir.FPMul(new_inst, up_factor)};
inst.ReplaceUsesWith(converted);
}
break; break;
} }
default: default:
break; break;
} }
@ -302,7 +313,7 @@ void RescalingPass(IR::Program& program) {
if (is_fragment_shader) { if (is_fragment_shader) {
for (IR::Block* const block : program.post_order_blocks) { for (IR::Block* const block : program.post_order_blocks) {
for (IR::Inst& inst : block->Instructions()) { for (IR::Inst& inst : block->Instructions()) {
VisitMark(inst); VisitMark(*block, inst);
} }
} }
} }