Mostly complete new GLSL translator (modulo flow control).
This commit is contained in:
parent
0058cae901
commit
2b3b423776
File diff suppressed because it is too large
Load Diff
|
@ -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,
|
||||
|
||||
|
|
|
@ -162,8 +162,8 @@
|
|||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.translationComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.translationComboBox.FormattingEnabled = true;
|
||||
this.translationComboBox.Items.AddRange(new object[] {
|
||||
"SPIRV"});
|
||||
this.translationComboBox.Items.AddRange(
|
||||
new object[]{"GLSL for GL4.5", "SPIRV"});
|
||||
this.translationComboBox.Location = new System.Drawing.Point(1224, 0);
|
||||
this.translationComboBox.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.translationComboBox.Name = "translationComboBox";
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.ComponentModel;
|
|||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
|
@ -18,6 +19,13 @@ namespace shader_playground {
|
|||
public Editor() {
|
||||
InitializeComponent();
|
||||
|
||||
var scrollUpdateTimer = new Timer();
|
||||
scrollUpdateTimer.Interval = 200;
|
||||
scrollUpdateTimer.Tick += (object sender, EventArgs e) => {
|
||||
UpdateScrollStates();
|
||||
};
|
||||
scrollUpdateTimer.Start();
|
||||
|
||||
var compilerBinPath = Path.Combine(Directory.GetCurrentDirectory(),
|
||||
Path.GetDirectoryName(compilerPath_));
|
||||
compilerWatcher_ = new FileSystemWatcher(compilerBinPath, "*.exe");
|
||||
|
@ -136,9 +144,9 @@ namespace shader_playground {
|
|||
var disassembledSourceCode = compiledShader.ErrorsAndWarnings;
|
||||
disassembledSourceCode = disassembledSourceCode.Replace("\n", Environment.NewLine);
|
||||
if (disassembledSourceCode.IndexOf("// PDB hint 00000000-00000000-00000000") == -1) {
|
||||
outputTextBox.Text = disassembledSourceCode;
|
||||
compilerUcodeTextBox.Text = "";
|
||||
wordsTextBox.Text = "";
|
||||
UpdateTextBox(outputTextBox, disassembledSourceCode, false);
|
||||
UpdateTextBox(compilerUcodeTextBox, "", false);
|
||||
UpdateTextBox(wordsTextBox, "", false);
|
||||
return;
|
||||
}
|
||||
var prefix = disassembledSourceCode.Substring(
|
||||
|
@ -155,7 +163,7 @@ namespace shader_playground {
|
|||
disassembledSourceCode =
|
||||
warnings + disassembledSourceCode.Substring(firstLine + 3);
|
||||
disassembledSourceCode = disassembledSourceCode.Trim();
|
||||
outputTextBox.Text = disassembledSourceCode;
|
||||
UpdateTextBox(outputTextBox, disassembledSourceCode, true);
|
||||
|
||||
string shaderType =
|
||||
shaderSourceCode.IndexOf("xvs_") == -1 ? "ps" : "vs";
|
||||
|
@ -163,7 +171,7 @@ namespace shader_playground {
|
|||
if (ucodeWords != null) {
|
||||
TryCompiler(shaderType, ucodeWords);
|
||||
} else {
|
||||
compilerUcodeTextBox.Text = "";
|
||||
UpdateTextBox(compilerUcodeTextBox, "", false);
|
||||
}
|
||||
|
||||
if (compilerUcodeTextBox.Text.Length > 0) {
|
||||
|
@ -191,7 +199,7 @@ namespace shader_playground {
|
|||
File.WriteAllBytes(ucodePath, ucodeBytes);
|
||||
|
||||
if (!File.Exists(compilerPath_)) {
|
||||
compilerUcodeTextBox.Text = "Compiler not found: " + compilerPath_;
|
||||
UpdateTextBox(compilerUcodeTextBox, "Compiler not found: " + compilerPath_, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -209,15 +217,18 @@ namespace shader_playground {
|
|||
process.WaitForExit();
|
||||
}
|
||||
string disasmText = File.ReadAllText(ucodeDisasmPath);
|
||||
compilerUcodeTextBox.Text = disasmText.Replace("\n", Environment.NewLine);
|
||||
UpdateTextBox(compilerUcodeTextBox, disasmText.Replace("\n", Environment.NewLine), true);
|
||||
} catch {
|
||||
compilerUcodeTextBox.Text = "COMPILER FAILURE";
|
||||
UpdateTextBox(compilerUcodeTextBox, "COMPILER FAILURE", false);
|
||||
}
|
||||
|
||||
string outputType;
|
||||
switch (translationComboBox.SelectedIndex) {
|
||||
default:
|
||||
case 0:
|
||||
outputType = "glsl45";
|
||||
break;
|
||||
case 1:
|
||||
outputType = "spirvtext";
|
||||
break;
|
||||
}
|
||||
|
@ -236,9 +247,9 @@ namespace shader_playground {
|
|||
process.WaitForExit();
|
||||
}
|
||||
string disasmText = File.ReadAllText(translatedDisasmPath);
|
||||
compilerTranslatedTextBox.Text = disasmText.Replace("\n", Environment.NewLine);
|
||||
UpdateTextBox(compilerTranslatedTextBox, disasmText.Replace("\n", Environment.NewLine), true);
|
||||
} catch {
|
||||
compilerTranslatedTextBox.Text = "COMPILER FAILURE";
|
||||
UpdateTextBox(compilerTranslatedTextBox, "COMPILER FAILURE", false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,6 +273,66 @@ namespace shader_playground {
|
|||
}
|
||||
}
|
||||
|
||||
void UpdateScrollStates() {
|
||||
foreach (var handle in scrollPreserve_.Keys) {
|
||||
if (scrollPreserve_[handle]) {
|
||||
var scrollInfo = new ScrollInfo();
|
||||
scrollInfo.cbSize = Marshal.SizeOf(scrollInfo);
|
||||
scrollInfo.fMask = (uint)ScrollInfoMask.SIF_TRACKPOS;
|
||||
bool hasScrollInfo = GetScrollInfo(handle, SB_VERT, ref scrollInfo);
|
||||
scrollPositions_[handle] = scrollInfo.nTrackPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<IntPtr, bool> scrollPreserve_ = new Dictionary<IntPtr, bool>();
|
||||
Dictionary<IntPtr, int> scrollPositions_ = new Dictionary<IntPtr, int>();
|
||||
void UpdateTextBox(TextBox textBox, string value, bool preserveScroll) {
|
||||
scrollPreserve_[textBox.Handle] = preserveScroll;
|
||||
|
||||
textBox.Text = value;
|
||||
|
||||
int previousScroll;
|
||||
if (!scrollPositions_.TryGetValue(textBox.Handle, out previousScroll)) {
|
||||
previousScroll = 0;
|
||||
}
|
||||
var scrollInfo = new ScrollInfo();
|
||||
scrollInfo.cbSize = Marshal.SizeOf(scrollInfo);
|
||||
scrollInfo.fMask = (uint)ScrollInfoMask.SIF_TRACKPOS;
|
||||
scrollInfo.nTrackPos = previousScroll;
|
||||
SetScrollInfo(textBox.Handle, SB_VERT, ref scrollInfo, 1);
|
||||
|
||||
var ptrWparam = new IntPtr(SB_THUMBPOSITION | previousScroll << 16);
|
||||
SendMessage(textBox.Handle, WM_VSCROLL, ptrWparam, IntPtr.Zero);
|
||||
}
|
||||
|
||||
private const int SB_VERT = 1;
|
||||
private const uint SB_THUMBPOSITION = 4;
|
||||
private const uint WM_VSCROLL = 0x115;
|
||||
public enum ScrollInfoMask : uint {
|
||||
SIF_RANGE = 0x1,
|
||||
SIF_PAGE = 0x2,
|
||||
SIF_POS = 0x4,
|
||||
SIF_DISABLENOSCROLL = 0x8,
|
||||
SIF_TRACKPOS = 0x10,
|
||||
SIF_ALL = (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS),
|
||||
}
|
||||
private struct ScrollInfo {
|
||||
public int cbSize;
|
||||
public uint fMask;
|
||||
public int nMin;
|
||||
public int nMax;
|
||||
public int nPage;
|
||||
public int nPos;
|
||||
public int nTrackPos;
|
||||
}
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
private static extern bool GetScrollInfo(IntPtr hwnd, int bar, ref ScrollInfo scrollInfo);
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
private static extern bool SetScrollInfo(IntPtr hwnd, int bar, ref ScrollInfo scrollInfo, int redraw);
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
bool MemCmp(byte[] a1, byte[] b1) {
|
||||
if (a1 == null || b1 == null) {
|
||||
return false;
|
||||
|
@ -281,7 +352,7 @@ namespace shader_playground {
|
|||
|
||||
uint[] ExtractAndDumpWords(string shaderType, byte[] shaderCode) {
|
||||
if (shaderCode == null || shaderCode.Length == 0) {
|
||||
wordsTextBox.Text = "";
|
||||
UpdateTextBox(wordsTextBox, "", false);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -302,7 +373,7 @@ namespace shader_playground {
|
|||
}
|
||||
sb.Append("};" + Environment.NewLine);
|
||||
sb.Append("shader_type = ShaderType::" + (shaderType == "vs" ? "kVertex" : "kPixel") + ";" + Environment.NewLine);
|
||||
wordsTextBox.Text = sb.ToString();
|
||||
UpdateTextBox(wordsTextBox, sb.ToString(), true);
|
||||
wordsTextBox.SelectAll();
|
||||
|
||||
return swappedCode;
|
||||
|
|
Loading…
Reference in New Issue