SPIR-V: WIP shader compiler / optimizations / alpha test implementation

This commit is contained in:
Dr. Chat
2016-05-15 12:01:38 -05:00
parent c06a7cdf81
commit 2bb52ef86b
11 changed files with 383 additions and 29 deletions

View File

@@ -0,0 +1,36 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/gpu/spirv/compiler.h"
namespace xe {
namespace gpu {
namespace spirv {
Compiler::Compiler() {}
void Compiler::AddPass(std::unique_ptr<CompilerPass> pass) {
compiler_passes_.push_back(std::move(pass));
}
bool Compiler::Compile(spv::Module* module) {
for (auto& pass : compiler_passes_) {
if (!pass->Run(module)) {
return false;
}
}
return true;
}
void Compiler::Reset() { compiler_passes_.clear(); }
} // namespace spirv
} // namespace gpu
} // namespace xe

View File

@@ -0,0 +1,41 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_GPU_SPIRV_COMPILER_H_
#define XENIA_GPU_SPIRV_COMPILER_H_
#include "xenia/base/arena.h"
#include "xenia/gpu/spirv/compiler_pass.h"
#include "third_party/glslang-spirv/SpvBuilder.h"
#include "third_party/spirv/GLSL.std.450.hpp11"
namespace xe {
namespace gpu {
namespace spirv {
// SPIR-V Compiler. Designed to optimize SPIR-V code before feeding it into the
// drivers.
class Compiler {
public:
Compiler();
void AddPass(std::unique_ptr<CompilerPass> pass);
void Reset();
bool Compile(spv::Module* module);
private:
std::vector<std::unique_ptr<CompilerPass>> compiler_passes_;
};
} // namespace spirv
} // namespace gpu
} // namespace xe
#endif // XENIA_GPU_SPIRV_COMPILER_H_

View File

@@ -0,0 +1,37 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_GPU_SPIRV_COMPILER_PASS_H_
#define XENIA_GPU_SPIRV_COMPILER_PASS_H_
#include "xenia/base/arena.h"
#include "third_party/glslang-spirv/SpvBuilder.h"
#include "third_party/spirv/GLSL.std.450.hpp11"
namespace xe {
namespace gpu {
namespace spirv {
class CompilerPass {
public:
CompilerPass() = default;
virtual ~CompilerPass() {}
virtual bool Run(spv::Module* module) = 0;
private:
xe::Arena ir_arena_;
};
} // namespace spirv
} // namespace gpu
} // namespace xe
#endif

View File

@@ -0,0 +1,30 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/gpu/spirv/passes/control_flow_analysis_pass.h"
namespace xe {
namespace gpu {
namespace spirv {
ControlFlowAnalysisPass::ControlFlowAnalysisPass() {}
bool ControlFlowAnalysisPass::Run(spv::Module* module) {
for (auto function : module->getFunctions()) {
// For each OpBranchConditional, see if we can find a point where control
// flow converges and then append an OpSelectionMerge.
// Potential problems: while loops constructed from branch instructions
}
return true;
}
} // namespace spirv
} // namespace gpu
} // namespace xe

View File

@@ -0,0 +1,34 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_GPU_SPIRV_PASSES_CONTROL_FLOW_ANALYSIS_PASS_H_
#define XENIA_GPU_SPIRV_PASSES_CONTROL_FLOW_ANALYSIS_PASS_H_
#include "xenia/gpu/spirv/compiler_pass.h"
namespace xe {
namespace gpu {
namespace spirv {
// Control-flow analysis pass. Runs through control-flow and adds merge opcodes
// where necessary.
class ControlFlowAnalysisPass : public CompilerPass {
public:
ControlFlowAnalysisPass();
bool Run(spv::Module* module) override;
private:
};
} // namespace spirv
} // namespace gpu
} // namespace xe
#endif // XENIA_GPU_SPIRV_PASSES_CONTROL_FLOW_ANALYSIS_PASS_H_

View File

@@ -0,0 +1,48 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/gpu/spirv/passes/control_flow_simplification_pass.h"
namespace xe {
namespace gpu {
namespace spirv {
ControlFlowSimplificationPass::ControlFlowSimplificationPass() {}
bool ControlFlowSimplificationPass::Run(spv::Module* module) {
for (auto function : module->getFunctions()) {
// Walk through the blocks in the function and merge any blocks which are
// unconditionally dominated.
for (auto it = function->getBlocks().end() - 1;
it != function->getBlocks().begin() - 1;) {
auto block = *it;
if (!block->isUnreachable() && block->getPredecessors().size() == 1) {
auto prev_block = block->getPredecessors()[0];
auto last_instr =
prev_block->getInstruction(prev_block->getInstructionCount() - 1);
if (last_instr->getOpCode() == spv::Op::OpBranch) {
if (prev_block->getSuccessors().size() == 1 &&
prev_block->getSuccessors()[0] == block) {
// We're dominated by this block. Merge into it.
prev_block->merge(block);
block->setUnreachable();
}
}
}
--it;
}
}
return true;
}
} // namespace spirv
} // namespace gpu
} // namespace xe

View File

@@ -0,0 +1,34 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_GPU_SPIRV_PASSES_CONTROL_FLOW_SIMPLIFICATION_PASS_H_
#define XENIA_GPU_SPIRV_PASSES_CONTROL_FLOW_SIMPLIFICATION_PASS_H_
#include "xenia/gpu/spirv/compiler_pass.h"
namespace xe {
namespace gpu {
namespace spirv {
// Control-flow simplification pass. Combines adjacent blocks and marks
// any unreachable blocks.
class ControlFlowSimplificationPass : public CompilerPass {
public:
ControlFlowSimplificationPass();
bool Run(spv::Module* module) override;
private:
};
} // namespace spirv
} // namespace gpu
} // namespace xe
#endif // XENIA_GPU_SPIRV_PASSES_CONTROL_FLOW_SIMPLIFICATION_PASS_H_