Mostly complete new GLSL translator (modulo flow control).

This commit is contained in:
Ben Vanik
2015-12-05 17:44:06 -08:00
parent 0058cae901
commit 2b3b423776
8 changed files with 1453 additions and 22 deletions

File diff suppressed because it is too large Load Diff

View 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_

View File

@@ -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>();
}

View File

@@ -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.

View File

@@ -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) {

View File

@@ -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,