aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2019-04-17 20:57:08 -0300
committerjduncanator <1518948+jduncanator@users.noreply.github.com>2019-04-18 09:57:08 +1000
commit6b23a2c125b9c48b5ebea92716004ef68698bb0f (patch)
tree69332df6fbbd8e2bddc522ba682fcc5c7a69e101 /Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs
parentb2e88b04a85b41cc60af3485d88c90429e84a218 (diff)
New shader translator implementation (#654)
* Start implementing a new shader translator * Fix shift instructions and a typo * Small refactoring on StructuredProgram, move RemovePhis method to a separate class * Initial geometry shader support * Implement TLD4 * Fix -- There's no negation on FMUL32I * Add constant folding and algebraic simplification optimizations, nits * Some leftovers from constant folding * Avoid cast for constant assignments * Add a branch elimination pass, and misc small fixes * Remove redundant branches, add expression propagation and other improvements on the code * Small leftovers -- add missing break and continue, remove unused properties, other improvements * Add null check to handle empty block cases on block visitor * Add HADD2 and HMUL2 half float shader instructions * Optimize pack/unpack sequences, some fixes related to half float instructions * Add TXQ, TLD, TLDS and TLD4S shader texture instructions, and some support for bindless textures, some refactoring on codegen * Fix copy paste mistake that caused RZ to be ignored on the AST instruction * Add workaround for conditional exit, and fix half float instruction with constant buffer * Add missing 0.0 source for TLDS.LZ variants * Simplify the switch for TLDS.LZ * Texture instructions related fixes * Implement the HFMA instruction, and some misc. fixes * Enable constant folding on UnpackHalf2x16 instructions * Refactor HFMA to use OpCode* for opcode decoding rather than on the helper methods * Remove the old shader translator * Remove ShaderDeclInfo and other unused things * Add dual vertex shader support * Add ShaderConfig, used to pass shader type and maximum cbuffer size * Move and rename some instruction enums * Move texture instructions into a separate file * Move operand GetExpression and locals management to OperandManager * Optimize opcode decoding using a simple list and binary search * Add missing condition for do-while on goto elimination * Misc. fixes on texture instructions * Simplify TLDS switch * Address PR feedback, and a nit
Diffstat (limited to 'Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs')
-rw-r--r--Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs206
1 files changed, 206 insertions, 0 deletions
diff --git a/Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs
new file mode 100644
index 00000000..5412d872
--- /dev/null
+++ b/Ryujinx.Graphics/Shader/CodeGen/Glsl/Declarations.cs
@@ -0,0 +1,206 @@
+using Ryujinx.Graphics.Gal;
+using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using Ryujinx.Graphics.Shader.StructuredIr;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
+{
+ static class Declarations
+ {
+ public static void Declare(CodeGenContext context, StructuredProgramInfo info)
+ {
+ context.AppendLine("#version 420 core");
+
+ context.AppendLine();
+
+ context.AppendLine($"const int {DefaultNames.UndefinedName} = 0;");
+
+ context.AppendLine();
+
+ if (context.Config.Type == GalShaderType.Geometry)
+ {
+ context.AppendLine("layout (points) in;");
+ context.AppendLine("layout (triangle_strip, max_vertices = 4) out;");
+
+ context.AppendLine();
+ }
+
+ context.AppendLine("layout (std140) uniform Extra");
+
+ context.EnterScope();
+
+ context.AppendLine("vec2 flip;");
+ context.AppendLine("int instance;");
+
+ context.LeaveScope(";");
+
+ context.AppendLine();
+
+ if (info.CBuffers.Count != 0)
+ {
+ DeclareUniforms(context, info);
+
+ context.AppendLine();
+ }
+
+ if (info.Samplers.Count != 0)
+ {
+ DeclareSamplers(context, info);
+
+ context.AppendLine();
+ }
+
+ if (info.IAttributes.Count != 0)
+ {
+ DeclareInputAttributes(context, info);
+
+ context.AppendLine();
+ }
+
+ if (info.OAttributes.Count != 0)
+ {
+ DeclareOutputAttributes(context, info);
+
+ context.AppendLine();
+ }
+ }
+
+ public static void DeclareLocals(CodeGenContext context, StructuredProgramInfo info)
+ {
+ foreach (AstOperand decl in info.Locals)
+ {
+ string name = context.OperandManager.DeclareLocal(decl);
+
+ context.AppendLine(GetVarTypeName(decl.VarType) + " " + name + ";");
+ }
+ }
+
+ private static string GetVarTypeName(VariableType type)
+ {
+ switch (type)
+ {
+ case VariableType.Bool: return "bool";
+ case VariableType.F32: return "float";
+ case VariableType.S32: return "int";
+ case VariableType.U32: return "uint";
+ }
+
+ throw new ArgumentException($"Invalid variable type \"{type}\".");
+ }
+
+ private static void DeclareUniforms(CodeGenContext context, StructuredProgramInfo info)
+ {
+ foreach (int cbufSlot in info.CBuffers.OrderBy(x => x))
+ {
+ string ubName = OperandManager.GetShaderStagePrefix(context.Config.Type);
+
+ ubName += "_" + DefaultNames.UniformNamePrefix + cbufSlot;
+
+ context.CBufferDescriptors.Add(new CBufferDescriptor(ubName, cbufSlot));
+
+ context.AppendLine("layout (std140) uniform " + ubName);
+
+ context.EnterScope();
+
+ string ubSize = "[" + NumberFormatter.FormatInt(context.Config.MaxCBufferSize / 16) + "]";
+
+ context.AppendLine("vec4 " + OperandManager.GetUbName(context.Config.Type, cbufSlot) + ubSize + ";");
+
+ context.LeaveScope(";");
+ }
+ }
+
+ private static void DeclareSamplers(CodeGenContext context, StructuredProgramInfo info)
+ {
+ Dictionary<string, AstTextureOperation> samplers = new Dictionary<string, AstTextureOperation>();
+
+ foreach (AstTextureOperation texOp in info.Samplers.OrderBy(x => x.Handle))
+ {
+ string samplerName = OperandManager.GetSamplerName(context.Config.Type, texOp);
+
+ if (!samplers.TryAdd(samplerName, texOp))
+ {
+ continue;
+ }
+
+ string samplerTypeName = GetSamplerTypeName(texOp.Type);
+
+ context.AppendLine("uniform " + samplerTypeName + " " + samplerName + ";");
+ }
+
+ foreach (KeyValuePair<string, AstTextureOperation> kv in samplers)
+ {
+ string samplerName = kv.Key;
+
+ AstTextureOperation texOp = kv.Value;
+
+ TextureDescriptor desc;
+
+ if ((texOp.Flags & TextureFlags.Bindless) != 0)
+ {
+ AstOperand operand = texOp.GetSource(0) as AstOperand;
+
+ desc = new TextureDescriptor(samplerName, operand.CbufSlot, operand.CbufOffset);
+ }
+ else
+ {
+ desc = new TextureDescriptor(samplerName, texOp.Handle);
+ }
+
+ context.TextureDescriptors.Add(desc);
+ }
+ }
+
+ private static void DeclareInputAttributes(CodeGenContext context, StructuredProgramInfo info)
+ {
+ string suffix = context.Config.Type == GalShaderType.Geometry ? "[]" : string.Empty;
+
+ foreach (int attr in info.IAttributes.OrderBy(x => x))
+ {
+ context.AppendLine($"layout (location = {attr}) in vec4 {DefaultNames.IAttributePrefix}{attr}{suffix};");
+ }
+ }
+
+ private static void DeclareOutputAttributes(CodeGenContext context, StructuredProgramInfo info)
+ {
+ foreach (int attr in info.OAttributes.OrderBy(x => x))
+ {
+ context.AppendLine($"layout (location = {attr}) out vec4 {DefaultNames.OAttributePrefix}{attr};");
+ }
+ }
+
+ private static string GetSamplerTypeName(TextureType type)
+ {
+ string typeName;
+
+ switch (type & TextureType.Mask)
+ {
+ case TextureType.Texture1D: typeName = "sampler1D"; break;
+ case TextureType.Texture2D: typeName = "sampler2D"; break;
+ case TextureType.Texture3D: typeName = "sampler3D"; break;
+ case TextureType.TextureCube: typeName = "samplerCube"; break;
+
+ default: throw new ArgumentException($"Invalid sampler type \"{type}\".");
+ }
+
+ if ((type & TextureType.Multisample) != 0)
+ {
+ typeName += "MS";
+ }
+
+ if ((type & TextureType.Array) != 0)
+ {
+ typeName += "Array";
+ }
+
+ if ((type & TextureType.Shadow) != 0)
+ {
+ typeName += "Shadow";
+ }
+
+ return typeName;
+ }
+ }
+} \ No newline at end of file