committed by
ameerj
12 changed files with 180 additions and 3 deletions
-
1src/shader_recompiler/CMakeLists.txt
-
1src/shader_recompiler/backend/spirv/emit_spirv.h
-
4src/shader_recompiler/backend/spirv/emit_spirv_control_flow.cpp
-
1src/shader_recompiler/frontend/ir/microinstruction.cpp
-
1src/shader_recompiler/frontend/ir/opcodes.inc
-
28src/shader_recompiler/frontend/maxwell/program.cpp
-
2src/shader_recompiler/frontend/maxwell/program.h
-
74src/shader_recompiler/ir_opt/dual_vertex_pass.cpp
-
26src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp
-
7src/shader_recompiler/ir_opt/passes.h
-
21src/shader_recompiler/ir_opt/texture_pass.cpp
-
17src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@ -0,0 +1,74 @@ |
|||||
|
// Copyright 2021 yuzu Emulator Project
|
||||
|
// Licensed under GPLv2 or any later version
|
||||
|
// Refer to the license.txt file included.
|
||||
|
|
||||
|
#include <algorithm>
|
||||
|
#include <ranges>
|
||||
|
#include <tuple>
|
||||
|
#include <type_traits>
|
||||
|
|
||||
|
#include "common/bit_cast.h"
|
||||
|
#include "common/bit_util.h"
|
||||
|
#include "shader_recompiler/exception.h"
|
||||
|
#include "shader_recompiler/frontend/ir/ir_emitter.h"
|
||||
|
#include "shader_recompiler/ir_opt/passes.h"
|
||||
|
|
||||
|
namespace Shader::Optimization { |
||||
|
|
||||
|
void VertexATransformPass(IR::Program& program) { |
||||
|
bool replaced_join{}; |
||||
|
bool eliminated_epilogue{}; |
||||
|
for (IR::Block* const block : program.post_order_blocks) { |
||||
|
for (IR::Inst& inst : block->Instructions()) { |
||||
|
switch (inst.GetOpcode()) { |
||||
|
case IR::Opcode::Return: |
||||
|
inst.ReplaceOpcode(IR::Opcode::Join); |
||||
|
replaced_join = true; |
||||
|
break; |
||||
|
case IR::Opcode::Epilogue: |
||||
|
inst.Invalidate(); |
||||
|
eliminated_epilogue = true; |
||||
|
break; |
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
if (replaced_join && eliminated_epilogue) { |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void VertexBTransformPass(IR::Program& program) { |
||||
|
for (IR::Block* const block : program.post_order_blocks | std::views::reverse) { |
||||
|
for (IR::Inst& inst : block->Instructions()) { |
||||
|
if (inst.GetOpcode() == IR::Opcode::Prologue) { |
||||
|
return inst.Invalidate(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void DualVertexJoinPass(IR::Program& program) { |
||||
|
const auto& blocks = program.blocks; |
||||
|
s64 s = static_cast<s64>(blocks.size()) - 1; |
||||
|
if (s < 1) { |
||||
|
throw NotImplementedException("Dual Vertex Join pass failed, expected atleast 2 blocks!"); |
||||
|
} |
||||
|
for (s64 index = 0; index < s; index++) { |
||||
|
IR::Block* const current_block = blocks[index]; |
||||
|
IR::Block* const next_block = blocks[index + 1]; |
||||
|
for (IR::Inst& inst : current_block->Instructions()) { |
||||
|
if (inst.GetOpcode() == IR::Opcode::Join) { |
||||
|
IR::IREmitter ir{*current_block, IR::Block::InstructionList::s_iterator_to(inst)}; |
||||
|
ir.Branch(next_block); |
||||
|
inst.Invalidate(); |
||||
|
// only 1 join should exist
|
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
throw NotImplementedException("Dual Vertex Join pass failed, no join present!"); |
||||
|
} |
||||
|
|
||||
|
} // namespace Shader::Optimization
|
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue