Mostly complete new GLSL translator (modulo flow control).
This commit is contained in:
1277
src/xenia/gpu/glsl_shader_translator.cc
Normal file
1277
src/xenia/gpu/glsl_shader_translator.cc
Normal file
File diff suppressed because it is too large
Load Diff
79
src/xenia/gpu/glsl_shader_translator.h
Normal file
79
src/xenia/gpu/glsl_shader_translator.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2015 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_GPU_GLSL_SHADER_TRANSLATOR_H_
|
||||
#define XENIA_GPU_GLSL_SHADER_TRANSLATOR_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "xenia/base/string_buffer.h"
|
||||
#include "xenia/gpu/shader_translator.h"
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
|
||||
class GlslShaderTranslator : public ShaderTranslator {
|
||||
public:
|
||||
enum class Dialect {
|
||||
kGL45,
|
||||
};
|
||||
|
||||
GlslShaderTranslator(Dialect dialect);
|
||||
~GlslShaderTranslator() override;
|
||||
|
||||
protected:
|
||||
void EmitTranslationError(const char* message) override;
|
||||
void EmitUnimplementedTranslationError() override;
|
||||
|
||||
void StartTranslation() override;
|
||||
std::vector<uint8_t> CompleteTranslation() override;
|
||||
|
||||
void ProcessLabel(uint32_t cf_index) override;
|
||||
void ProcessControlFlowNopInstruction() override;
|
||||
void ProcessExecInstructionBegin(const ParsedExecInstruction& instr) override;
|
||||
void ProcessExecInstructionEnd(const ParsedExecInstruction& instr) override;
|
||||
void ProcessLoopStartInstruction(
|
||||
const ParsedLoopStartInstruction& instr) override;
|
||||
void ProcessLoopEndInstruction(
|
||||
const ParsedLoopEndInstruction& instr) override;
|
||||
void ProcessCallInstruction(const ParsedCallInstruction& instr) override;
|
||||
void ProcessReturnInstruction(const ParsedReturnInstruction& instr) override;
|
||||
void ProcessJumpInstruction(const ParsedJumpInstruction& instr) override;
|
||||
void ProcessAllocInstruction(const ParsedAllocInstruction& instr) override;
|
||||
void ProcessVertexFetchInstruction(
|
||||
const ParsedVertexFetchInstruction& instr) override;
|
||||
void ProcessTextureFetchInstruction(
|
||||
const ParsedTextureFetchInstruction& instr) override;
|
||||
void ProcessAluInstruction(const ParsedAluInstruction& instr) override;
|
||||
|
||||
private:
|
||||
void Indent();
|
||||
void Unindent();
|
||||
|
||||
void EmitLoadOperand(size_t i, const InstructionOperand& op);
|
||||
void EmitStoreVectorResult(const InstructionResult& result);
|
||||
void EmitStoreScalarResult(const InstructionResult& result);
|
||||
void EmitStoreResult(const InstructionResult& result, const char* temp);
|
||||
|
||||
Dialect dialect_;
|
||||
|
||||
StringBuffer source_;
|
||||
int depth_ = 0;
|
||||
char depth_prefix_[16] = {0};
|
||||
|
||||
void ProcessVectorAluInstruction(const ParsedAluInstruction& instr);
|
||||
void ProcessScalarAluInstruction(const ParsedAluInstruction& instr);
|
||||
};
|
||||
|
||||
} // namespace gpu
|
||||
} // namespace xe
|
||||
|
||||
#endif // XENIA_GPU_GLSL_SHADER_TRANSLATOR_H_
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/main.h"
|
||||
#include "xenia/base/string.h"
|
||||
#include "xenia/gpu/glsl_shader_translator.h"
|
||||
#include "xenia/gpu/shader_translator.h"
|
||||
#include "xenia/gpu/spirv_shader_translator.h"
|
||||
#include "xenia/ui/spirv/spirv_disassembler.h"
|
||||
@@ -25,7 +26,7 @@ DEFINE_string(shader_input_type, "",
|
||||
"'vs', 'ps', or unspecified to infer from the given filename.");
|
||||
DEFINE_string(shader_output, "", "Output shader file path.");
|
||||
DEFINE_string(shader_output_type, "ucode",
|
||||
"Translator to use: [ucode, spirv, spirvtext].");
|
||||
"Translator to use: [ucode, glsl45, spirv, spirvtext].");
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
@@ -82,6 +83,9 @@ int shader_compiler_main(const std::vector<std::wstring>& args) {
|
||||
if (FLAGS_shader_output_type == "spirv" ||
|
||||
FLAGS_shader_output_type == "spirvtext") {
|
||||
translator = std::make_unique<SpirvShaderTranslator>();
|
||||
} else if (FLAGS_shader_output_type == "glsl45") {
|
||||
translator = std::make_unique<GlslShaderTranslator>(
|
||||
GlslShaderTranslator::Dialect::kGL45);
|
||||
} else {
|
||||
translator = std::make_unique<UcodeShaderTranslator>();
|
||||
}
|
||||
|
||||
@@ -537,10 +537,10 @@ class ShaderTranslator {
|
||||
// Ucode disassembly buffer accumulated during translation.
|
||||
StringBuffer& ucode_disasm_buffer() { return ucode_disasm_buffer_; }
|
||||
// Emits a translation error that will be passed back in the result.
|
||||
void EmitTranslationError(const char* message);
|
||||
virtual void EmitTranslationError(const char* message);
|
||||
// Emits a translation error indicating that the current translation is not
|
||||
// implemented or supported.
|
||||
void EmitUnimplementedTranslationError();
|
||||
virtual void EmitUnimplementedTranslationError();
|
||||
|
||||
// Handles the start of translation.
|
||||
// At this point the vertex and texture bindings have been gathered.
|
||||
|
||||
@@ -91,6 +91,9 @@ void DisassembleSourceOperand(const InstructionOperand& op, StringBuffer* out) {
|
||||
out->Append('b');
|
||||
break;
|
||||
}
|
||||
if (op.is_absolute_value) {
|
||||
out->Append("_abs");
|
||||
}
|
||||
switch (op.storage_addressing_mode) {
|
||||
case InstructionStorageAddressingMode::kStatic:
|
||||
out->AppendFormat("%d", op.storage_index);
|
||||
@@ -102,9 +105,6 @@ void DisassembleSourceOperand(const InstructionOperand& op, StringBuffer* out) {
|
||||
out->AppendFormat("[%d+aL]", op.storage_index);
|
||||
break;
|
||||
}
|
||||
if (op.is_absolute_value) {
|
||||
out->Append("_abs");
|
||||
}
|
||||
if (!op.is_standard_swizzle()) {
|
||||
out->Append('.');
|
||||
if (op.component_count == 1) {
|
||||
|
||||
@@ -933,7 +933,7 @@ enum class AluScalarOpcode {
|
||||
// if (src0.a == 0.0) {
|
||||
// dest.xyzw = 1.0;
|
||||
// } else {
|
||||
// dest.xyzw = src1.a;
|
||||
// dest.xyzw = src0.a;
|
||||
// }
|
||||
// p0 = 0;
|
||||
// }
|
||||
@@ -1186,7 +1186,7 @@ enum class AluVectorOpcode {
|
||||
|
||||
// Two-Element Dot Product and Add
|
||||
// dp2add dest, src0, src1, src2
|
||||
// dest.xyzw = src0.x * src1.x + src0.y * src1.y + src3.x;
|
||||
// dest.xyzw = src0.x * src1.x + src0.y * src1.y + src2.x;
|
||||
// Note: only pv.x contains the value.
|
||||
kDp2Add = 17,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user