Work continues

This commit is contained in:
gdkchan 2018-03-30 23:14:07 -03:00
parent 0dc4053599
commit bac72e1613
8 changed files with 121 additions and 84 deletions

View file

@ -23,7 +23,7 @@ namespace Ryujinx.Graphics.Gal
//Shader
void CreateShader(long Tag, byte[] Data, GalShaderType Type);
void SetShaderCb(int Cbuf, byte[] Data);
void SetShaderCb(long Tag, int Cbuf, byte[] Data);
void BindShader(long Tag);
void SendVertexBuffer(int Index, byte[] Buffer, int Stride, GalVertexAttrib[] Attribs);

View file

@ -3,6 +3,7 @@ using Ryujinx.Graphics.Gal.Shader;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Ryujinx.Graphics.Gal.OpenGL
{
@ -14,11 +15,19 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public GalShaderType Type { get; private set; }
public ShaderStage(GalShaderType Type)
public ICollection<ShaderDeclInfo> TextureUsage { get; private set; }
public ICollection<ShaderDeclInfo> UniformUsage { get; private set; }
public ShaderStage(
GalShaderType Type,
ICollection<ShaderDeclInfo> TextureUsage,
ICollection<ShaderDeclInfo> UniformUsage)
{
Handle = GL.CreateShader(OGLEnumConverter.GetShaderType(Type));
this.Type = Type;
this.Type = Type;
this.TextureUsage = TextureUsage;
this.UniformUsage = UniformUsage;
}
public void Dispose()
@ -63,21 +72,30 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
if (!Stages.ContainsKey(Tag))
{
string Glsl = GetGlslCode(Data, Type);
GlslProgram Program = GetGlslProgram(Data, Type);
System.Console.WriteLine(Glsl);
System.Console.WriteLine(Program.Code);
ShaderStage Stage = new ShaderStage(Type);
ShaderStage Stage = new ShaderStage(
Type,
Program.Textures,
Program.Uniforms);
Stages.Add(Tag, Stage);
CompileAndCheck(Stage.Handle, Glsl);
CompileAndCheck(Stage.Handle, Program.Code);
}
}
public void SetConstBuffer(int Cbuf, byte[] Data)
public void SetConstBuffer(long Tag, int Cbuf, byte[] Data)
{
if (Stages.TryGetValue(Tag, out ShaderStage Stage))
{
foreach (ShaderDeclInfo DeclInfo in Stage.UniformUsage.Where(x => x.Cbuf == Cbuf))
{
float Value = BitConverter.ToSingle(Data, DeclInfo.Index * 4);
}
}
}
public void Bind(long Tag)
@ -138,7 +156,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
}
}
private string GetGlslCode(byte[] Data, GalShaderType Type)
private GlslProgram GetGlslProgram(byte[] Data, GalShaderType Type)
{
int[] Code = new int[(Data.Length - 0x50) >> 2];
@ -156,7 +174,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
GlslDecompiler Decompiler = new GlslDecompiler();
return Decompiler.Decompile(Code, Type).Code;
return Decompiler.Decompile(Code, Type);
}
private static void CompileAndCheck(int Handle, string Code)

View file

@ -197,7 +197,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
case GalVertexAttribType.Sint:
case GalVertexAttribType.Uint:
case GalVertexAttribType.Uscaled:
case GalVertexAttribType.Sscaled:
case GalVertexAttribType.Sscaled:
{
switch (Attrib.Size)
{
@ -287,7 +287,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
GL.ActiveTexture(TextureUnit.Texture0 + Index);
GL.BindTexture(TextureTarget.Texture2D, Textures[Index].Handle);
GL.BindTexture(TextureTarget.Texture2D, Textures[Index].Handle);
}
public void CreateShader(long Tag, byte[] Data, GalShaderType Type)
@ -300,14 +300,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL
ActionsQueue.Enqueue(() => Shader.Create(Tag, Data, Type));
}
public void SetShaderCb(int Cbuf, byte[] Data)
public void SetShaderCb(long Tag, int Cbuf, byte[] Data)
{
if (Data == null)
{
throw new ArgumentNullException(nameof(Data));
}
ActionsQueue.Enqueue(() => Shader.SetConstBuffer(Cbuf, Data));
ActionsQueue.Enqueue(() => Shader.SetConstBuffer(Tag, Cbuf, Data));
}
public void BindShader(long Tag)

View file

@ -16,15 +16,15 @@ namespace Ryujinx.Graphics.Gal.Shader
private static string[] ElemTypes = new string[] { "float", "vec2", "vec3", "vec4" };
private Dictionary<int, GlslDeclInfo> Textures;
private Dictionary<int, ShaderDeclInfo> Textures;
private Dictionary<(int, int), GlslDeclInfo> Uniforms;
private Dictionary<(int, int), ShaderDeclInfo> Uniforms;
private Dictionary<int, GlslDeclInfo> InputAttributes;
private Dictionary<int, GlslDeclInfo> OutputAttributes;
private Dictionary<int, ShaderDeclInfo> InAttributes;
private Dictionary<int, ShaderDeclInfo> OutAttributes;
private Dictionary<int, GlslDeclInfo> Gprs;
private Dictionary<int, GlslDeclInfo> Preds;
private Dictionary<int, ShaderDeclInfo> Gprs;
private Dictionary<int, ShaderDeclInfo> Preds;
private const int AttrStartIndex = 8;
private const int TexStartIndex = 8;
@ -74,26 +74,26 @@ namespace Ryujinx.Graphics.Gal.Shader
public GlslProgram Decompile(int[] Code, GalShaderType Type)
{
Uniforms = new Dictionary<(int, int), GlslDeclInfo>();
Uniforms = new Dictionary<(int, int), ShaderDeclInfo>();
Textures = new Dictionary<int, GlslDeclInfo>();
Textures = new Dictionary<int, ShaderDeclInfo>();
InputAttributes = new Dictionary<int, GlslDeclInfo>();
OutputAttributes = new Dictionary<int, GlslDeclInfo>();
InAttributes = new Dictionary<int, ShaderDeclInfo>();
OutAttributes = new Dictionary<int, ShaderDeclInfo>();
Gprs = new Dictionary<int, GlslDeclInfo>();
Preds = new Dictionary<int, GlslDeclInfo>();
Gprs = new Dictionary<int, ShaderDeclInfo>();
Preds = new Dictionary<int, ShaderDeclInfo>();
SB = new StringBuilder();
//FIXME: Only valid for vertex shaders.
if (Type == GalShaderType.Fragment)
{
Gprs.Add(0, new GlslDeclInfo("FragColor", 0, 0, 4));
Gprs.Add(0, new ShaderDeclInfo("FragColor", 0, 0, 4));
}
else
{
OutputAttributes.Add(7, new GlslDeclInfo("gl_Position", -1, 0, 4));
OutAttributes.Add(7, new ShaderDeclInfo("gl_Position", -1, 0, 4));
}
ShaderIrBlock Block = ShaderDecoder.DecodeBasicBlock(Code, 0, Type);
@ -116,15 +116,12 @@ namespace Ryujinx.Graphics.Gal.Shader
PrintBlockScope("void main()", 1, Nodes);
GlslProgram Program = new GlslProgram();
string GlslCode = SB.ToString();
Program.Code = SB.ToString();
Program.Attributes = InputAttributes.Values.ToArray();
SB.Clear();
return Program;
return new GlslProgram(
GlslCode,
Textures.Values,
Uniforms.Values);
}
private void Traverse(ShaderIrNode Parent, ShaderIrNode Node)
@ -164,7 +161,7 @@ namespace Ryujinx.Graphics.Gal.Shader
string Name = $"{TextureName}{Index}";
Textures.TryAdd(Handle, new GlslDeclInfo(Name, Index));
Textures.TryAdd(Handle, new ShaderDeclInfo(Name, Index));
}
break;
}
@ -173,7 +170,7 @@ namespace Ryujinx.Graphics.Gal.Shader
{
string Name = $"{UniformName}{Cbuf.Index}_{Cbuf.Offs}";
GlslDeclInfo DeclInfo = new GlslDeclInfo(Name, Cbuf.Offs, Cbuf.Index);
ShaderDeclInfo DeclInfo = new ShaderDeclInfo(Name, Cbuf.Offs, Cbuf.Index);
Uniforms.TryAdd((Cbuf.Index, Cbuf.Offs), DeclInfo);
@ -187,24 +184,24 @@ namespace Ryujinx.Graphics.Gal.Shader
int GlslIndex = Index - AttrStartIndex;
GlslDeclInfo DeclInfo;
ShaderDeclInfo DeclInfo;
if (Parent is ShaderIrAsg Asg && Asg.Dst == Node)
{
if (!OutputAttributes.TryGetValue(Index, out DeclInfo))
if (!OutAttributes.TryGetValue(Index, out DeclInfo))
{
DeclInfo = new GlslDeclInfo(OutputName + GlslIndex, GlslIndex);
DeclInfo = new ShaderDeclInfo(OutputName + GlslIndex, GlslIndex);
OutputAttributes.Add(Index, DeclInfo);
OutAttributes.Add(Index, DeclInfo);
}
}
else
{
if (!InputAttributes.TryGetValue(Index, out DeclInfo))
if (!InAttributes.TryGetValue(Index, out DeclInfo))
{
DeclInfo = new GlslDeclInfo(InputAttrName + GlslIndex, GlslIndex);
DeclInfo = new ShaderDeclInfo(InputAttrName + GlslIndex, GlslIndex);
InputAttributes.Add(Index, DeclInfo);
InAttributes.Add(Index, DeclInfo);
}
}
@ -219,7 +216,7 @@ namespace Ryujinx.Graphics.Gal.Shader
{
string Name = $"{GprName}{Gpr.Index}";
Gprs.TryAdd(Gpr.Index, new GlslDeclInfo(Name, Gpr.Index));
Gprs.TryAdd(Gpr.Index, new ShaderDeclInfo(Name, Gpr.Index));
}
break;
}
@ -230,7 +227,7 @@ namespace Ryujinx.Graphics.Gal.Shader
{
string Name = $"{PredName}{Pred.Index}";
Preds.TryAdd(Pred.Index, new GlslDeclInfo(Name, Pred.Index));
Preds.TryAdd(Pred.Index, new ShaderDeclInfo(Name, Pred.Index));
}
break;
}
@ -244,7 +241,7 @@ namespace Ryujinx.Graphics.Gal.Shader
private void PrintDeclUniforms()
{
foreach (GlslDeclInfo DeclInfo in Uniforms.Values.OrderBy(DeclKeySelector))
foreach (ShaderDeclInfo DeclInfo in Uniforms.Values.OrderBy(DeclKeySelector))
{
SB.AppendLine($"uniform {GetDecl(DeclInfo)};");
}
@ -257,19 +254,19 @@ namespace Ryujinx.Graphics.Gal.Shader
private void PrintDeclInAttributes()
{
PrintDeclAttributes(InputAttributes.Values, "in");
PrintDeclAttributes(InAttributes.Values, "in");
}
private void PrintDeclOutAttributes()
{
PrintDeclAttributes(OutputAttributes.Values, "out");
PrintDeclAttributes(OutAttributes.Values, "out");
}
private void PrintDeclAttributes(ICollection<GlslDeclInfo> Decls, string InOut)
private void PrintDeclAttributes(ICollection<ShaderDeclInfo> Decls, string InOut)
{
bool PrintNl = false;
foreach (GlslDeclInfo DeclInfo in Decls.OrderBy(DeclKeySelector))
foreach (ShaderDeclInfo DeclInfo in Decls.OrderBy(DeclKeySelector))
{
if (DeclInfo.Index >= 0)
{
@ -295,9 +292,9 @@ namespace Ryujinx.Graphics.Gal.Shader
PrintDecls(Preds.Values, "bool");
}
private void PrintDecls(ICollection<GlslDeclInfo> Decls, string CustomType = null)
private void PrintDecls(ICollection<ShaderDeclInfo> Decls, string CustomType = null)
{
foreach (GlslDeclInfo DeclInfo in Decls.OrderBy(DeclKeySelector))
foreach (ShaderDeclInfo DeclInfo in Decls.OrderBy(DeclKeySelector))
{
string Name;
@ -319,12 +316,12 @@ namespace Ryujinx.Graphics.Gal.Shader
}
}
private int DeclKeySelector(GlslDeclInfo DeclInfo)
private int DeclKeySelector(ShaderDeclInfo DeclInfo)
{
return DeclInfo.Cbuf << 24 | DeclInfo.Index;
}
private string GetDecl(GlslDeclInfo DeclInfo)
private string GetDecl(ShaderDeclInfo DeclInfo)
{
return $"{ElemTypes[DeclInfo.Size - 1]} {DeclInfo.Name}";
}
@ -362,14 +359,9 @@ namespace Ryujinx.Graphics.Gal.Shader
PrintBlockScope(SubScopeName, IdentationLevel + 1, Cond.Child);
}
else if (Node is ShaderIrAsg Asg)
else if (Node is ShaderIrAsg Asg && IsValidOutOper(Asg.Dst))
{
if (IsValidOutOper(Asg.Dst))
{
SB.AppendLine(Identation +
$"{GetOutOperName(Asg.Dst)} = " +
$"{GetInOperName (Asg.Src, true)};");
}
SB.AppendLine($"{Identation}{GetOutOperName(Asg.Dst)} = {GetInOperName(Asg.Src, true)};");
}
else if (Node is ShaderIrOp Op)
{
@ -469,7 +461,7 @@ namespace Ryujinx.Graphics.Gal.Shader
private string GetName(ShaderIrOperCbuf Cbuf)
{
if (!Uniforms.TryGetValue((Cbuf.Index, Cbuf.Offs), out GlslDeclInfo DeclInfo))
if (!Uniforms.TryGetValue((Cbuf.Index, Cbuf.Offs), out ShaderDeclInfo DeclInfo))
{
throw new InvalidOperationException();
}
@ -479,20 +471,20 @@ namespace Ryujinx.Graphics.Gal.Shader
private string GetOutAbufName(ShaderIrOperAbuf Abuf)
{
return GetName(OutputAttributes, Abuf, Swizzle: true);
return GetName(OutAttributes, Abuf, Swizzle: true);
}
private string GetName(ShaderIrOperAbuf Abuf, bool Swizzle = true)
{
return GetName(InputAttributes, Abuf, Swizzle);
return GetName(InAttributes, Abuf, Swizzle);
}
private string GetName(Dictionary<int, GlslDeclInfo> Decls, ShaderIrOperAbuf Abuf, bool Swizzle)
private string GetName(Dictionary<int, ShaderDeclInfo> Decls, ShaderIrOperAbuf Abuf, bool Swizzle)
{
int Index = Abuf.Offs >> 4;
int Elem = (Abuf.Offs >> 2) & 3;
if (!Decls.TryGetValue(Index, out GlslDeclInfo DeclInfo))
if (!Decls.TryGetValue(Index, out ShaderDeclInfo DeclInfo))
{
throw new InvalidOperationException();
}
@ -517,11 +509,11 @@ namespace Ryujinx.Graphics.Gal.Shader
return Pred.IsConst ? "true" : GetNameWithSwizzle(Preds, Pred.Index);
}
private string GetNameWithSwizzle(Dictionary<int, GlslDeclInfo> Decls, int Index)
private string GetNameWithSwizzle(Dictionary<int, ShaderDeclInfo> Decls, int Index)
{
int VecIndex = Index >> 2;
if (Decls.TryGetValue(VecIndex, out GlslDeclInfo DeclInfo))
if (Decls.TryGetValue(VecIndex, out ShaderDeclInfo DeclInfo))
{
if (DeclInfo.Size > 1 && Index < VecIndex + DeclInfo.Size)
{
@ -674,7 +666,7 @@ namespace Ryujinx.Graphics.Gal.Shader
int Handle = ((ShaderIrOperImm)Op.OperandC).Imm;
if (!Textures.TryGetValue(Handle, out GlslDeclInfo DeclInfo))
if (!Textures.TryGetValue(Handle, out ShaderDeclInfo DeclInfo))
{
throw new InvalidOperationException();
}

View file

@ -1,10 +1,22 @@
using System.Collections.Generic;
namespace Ryujinx.Graphics.Gal.Shader
{
struct GlslProgram
{
public string Code;
public string Code { get; private set; }
public GlslDeclInfo[] ConstBuffers;
public GlslDeclInfo[] Attributes;
public ICollection<ShaderDeclInfo> Textures { get; private set; }
public ICollection<ShaderDeclInfo> Uniforms { get; private set; }
public GlslProgram(
string Code,
ICollection<ShaderDeclInfo> Textures,
ICollection<ShaderDeclInfo> Uniforms)
{
this.Code = Code;
this.Textures = Textures;
this.Uniforms = Uniforms;
}
}
}

View file

@ -1,6 +1,6 @@
namespace Ryujinx.Graphics.Gal.Shader
namespace Ryujinx.Graphics.Gal
{
public class GlslDeclInfo
public class ShaderDeclInfo
{
public string Name { get; private set; }
@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Gal.Shader
public int Cbuf { get; private set; }
public int Size { get; private set; }
public GlslDeclInfo(string Name, int Index, int Cbuf = 0, int Size = 1)
public ShaderDeclInfo(string Name, int Index, int Cbuf = 0, int Size = 1)
{
this.Name = Name;
this.Index = Index;
@ -16,7 +16,7 @@ namespace Ryujinx.Graphics.Gal.Shader
this.Size = Size;
}
public void Enlarge(int NewSize)
internal void Enlarge(int NewSize)
{
if (Size < NewSize)
{

View file

@ -89,7 +89,23 @@ namespace Ryujinx.Graphics.Gpu
byte[] Code = AMemoryHelper.ReadBytes(Memory, Position, (uint)Size);
Gpu.Renderer.CreateShader(Position, Code, GetTypeFromProgram(Index));
GalShaderType ShaderType = GetTypeFromProgram(Index);
Gpu.Renderer.CreateShader(Position, Code, ShaderType);
for (int Cbuf = 0; Cbuf < Cbs.Length; Cbuf++)
{
ConstBuffer Cb = Cbs[Cbuf];
if (Cb.Enabled)
{
long CbPosition = Cb.Position + (int)ShaderType * Cb.Size;
byte[] Data = AMemoryHelper.ReadBytes(Memory, CbPosition, (uint)Cb.Size);
Gpu.Renderer.SetShaderCb(Position, Cbuf, Data);
}
}
}
}
@ -155,10 +171,9 @@ namespace Ryujinx.Graphics.Gpu
if (TryGetCpuAddr(NvGpuEngine3dReg.CbAddress, out long Position))
{
Cbs[Index].Position = Position;
Cbs[Index].Enabled = Enabled;
Cbs[Index].Size = ReadRegister(NvGpuEngine3dReg.CbSize);
}
Cbs[Index].Enabled = Enabled;
Cbs[Index].Size = ReadRegister(NvGpuEngine3dReg.CbSize);
}
private int ReadCb(AMemory Memory, int Cbuf, int Offset)

View file

@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.Gpu
{
public class NvGpuFifo
{
private const int MacrosCount = 32;
private const int MacrosCount = 0x80;
private const int MacroIndexMask = MacrosCount - 1;
private NsGpu Gpu;