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