mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-01-09 12:19:12 +00:00
Implement non-2D textures in shaders
This commit is contained in:
parent
a42ab2e40c
commit
30d7d3ae0a
16 changed files with 375 additions and 87 deletions
|
@ -4,8 +4,10 @@ namespace Ryujinx.Graphics.Gal
|
||||||
{
|
{
|
||||||
public int Width;
|
public int Width;
|
||||||
public int Height;
|
public int Height;
|
||||||
|
public int Depth;
|
||||||
|
|
||||||
public GalImageFormat Format;
|
public GalImageFormat Format;
|
||||||
|
public GalImageTarget Target;
|
||||||
|
|
||||||
public GalTextureSource XSource;
|
public GalTextureSource XSource;
|
||||||
public GalTextureSource YSource;
|
public GalTextureSource YSource;
|
||||||
|
@ -15,7 +17,9 @@ namespace Ryujinx.Graphics.Gal
|
||||||
public GalImage(
|
public GalImage(
|
||||||
int Width,
|
int Width,
|
||||||
int Height,
|
int Height,
|
||||||
|
int Depth,
|
||||||
GalImageFormat Format,
|
GalImageFormat Format,
|
||||||
|
GalImageTarget Target,
|
||||||
GalTextureSource XSource = GalTextureSource.Red,
|
GalTextureSource XSource = GalTextureSource.Red,
|
||||||
GalTextureSource YSource = GalTextureSource.Green,
|
GalTextureSource YSource = GalTextureSource.Green,
|
||||||
GalTextureSource ZSource = GalTextureSource.Blue,
|
GalTextureSource ZSource = GalTextureSource.Blue,
|
||||||
|
@ -23,7 +27,9 @@ namespace Ryujinx.Graphics.Gal
|
||||||
{
|
{
|
||||||
this.Width = Width;
|
this.Width = Width;
|
||||||
this.Height = Height;
|
this.Height = Height;
|
||||||
|
this.Depth = Depth;
|
||||||
this.Format = Format;
|
this.Format = Format;
|
||||||
|
this.Target = Target;
|
||||||
this.XSource = XSource;
|
this.XSource = XSource;
|
||||||
this.YSource = YSource;
|
this.YSource = YSource;
|
||||||
this.ZSource = ZSource;
|
this.ZSource = ZSource;
|
||||||
|
|
15
Ryujinx.Graphics/Gal/GalImageType.cs
Normal file
15
Ryujinx.Graphics/Gal/GalImageType.cs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
namespace Ryujinx.Graphics.Gal
|
||||||
|
{
|
||||||
|
public enum GalImageTarget
|
||||||
|
{
|
||||||
|
_1d = 0,
|
||||||
|
_2d = 1,
|
||||||
|
_3d = 2,
|
||||||
|
CubeMap = 3,
|
||||||
|
_1dArray = 4,
|
||||||
|
_2dArray = 5,
|
||||||
|
_1dBuffer = 6,
|
||||||
|
_2dNoMimap = 7, //GL_TEXTURE_RECTANGLE?
|
||||||
|
CubeArray = 8,
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,6 @@ namespace Ryujinx.Graphics.Gal
|
||||||
|
|
||||||
void Bind(long Key, int Index);
|
void Bind(long Key, int Index);
|
||||||
|
|
||||||
void SetSampler(GalTextureSampler Sampler);
|
void SetSampler(long Key, GalTextureSampler Sampler);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -34,13 +34,12 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
public ImageHandler(int Handle, GalImage Image)
|
public ImageHandler(int Handle, GalImage Image)
|
||||||
{
|
{
|
||||||
this.Handle = Handle;
|
this.Handle = Handle;
|
||||||
|
this.Image = Image;
|
||||||
this.Image = Image;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EnsureSetup(GalImage Image)
|
public void EnsureSetup(GalImage Image)
|
||||||
{
|
{
|
||||||
if (Width != Image.Width ||
|
if (Width != Image.Width ||
|
||||||
Height != Image.Height ||
|
Height != Image.Height ||
|
||||||
Format != Image.Format ||
|
Format != Image.Format ||
|
||||||
!Initialized)
|
!Initialized)
|
||||||
|
@ -48,7 +47,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
(PixelInternalFormat InternalFormat, PixelFormat PixelFormat, PixelType PixelType) =
|
(PixelInternalFormat InternalFormat, PixelFormat PixelFormat, PixelType PixelType) =
|
||||||
OGLEnumConverter.GetImageFormat(Image.Format);
|
OGLEnumConverter.GetImageFormat(Image.Format);
|
||||||
|
|
||||||
GL.BindTexture(TextureTarget.Texture2D, Handle);
|
TextureTarget Target = OGLEnumConverter.GetImageTarget(Image.Target);
|
||||||
|
|
||||||
|
GL.BindTexture(Target, Handle);
|
||||||
|
|
||||||
if (Initialized)
|
if (Initialized)
|
||||||
{
|
{
|
||||||
|
@ -72,7 +73,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
GL.BufferData(BufferTarget.PixelPackBuffer, CurrentSize, IntPtr.Zero, BufferUsageHint.StreamCopy);
|
GL.BufferData(BufferTarget.PixelPackBuffer, CurrentSize, IntPtr.Zero, BufferUsageHint.StreamCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
GL.GetTexImage(TextureTarget.Texture2D, 0, this.PixelFormat, this.PixelType, IntPtr.Zero);
|
GL.GetTexImage(Target, 0, this.PixelFormat, this.PixelType, IntPtr.Zero);
|
||||||
|
|
||||||
GL.DeleteTexture(Handle);
|
GL.DeleteTexture(Handle);
|
||||||
|
|
||||||
|
@ -84,22 +85,44 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
const int MinFilter = (int)TextureMinFilter.Linear;
|
const int MinFilter = (int)TextureMinFilter.Linear;
|
||||||
const int MagFilter = (int)TextureMagFilter.Linear;
|
const int MagFilter = (int)TextureMagFilter.Linear;
|
||||||
|
|
||||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, MinFilter);
|
GL.TexParameter(Target, TextureParameterName.TextureMinFilter, MinFilter);
|
||||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, MagFilter);
|
GL.TexParameter(Target, TextureParameterName.TextureMagFilter, MagFilter);
|
||||||
|
|
||||||
const int Level = 0;
|
const int Level = 0;
|
||||||
const int Border = 0;
|
const int Border = 0;
|
||||||
|
|
||||||
GL.TexImage2D(
|
switch (Target)
|
||||||
TextureTarget.Texture2D,
|
{
|
||||||
Level,
|
case TextureTarget.Texture2D:
|
||||||
InternalFormat,
|
GL.TexImage2D(
|
||||||
Image.Width,
|
Target,
|
||||||
Image.Height,
|
Level,
|
||||||
Border,
|
InternalFormat,
|
||||||
PixelFormat,
|
Image.Width,
|
||||||
PixelType,
|
Image.Height,
|
||||||
IntPtr.Zero);
|
Border,
|
||||||
|
PixelFormat,
|
||||||
|
PixelType,
|
||||||
|
IntPtr.Zero);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TextureTarget.Texture2DArray:
|
||||||
|
GL.TexImage3D(
|
||||||
|
Target,
|
||||||
|
Level,
|
||||||
|
InternalFormat,
|
||||||
|
Image.Width,
|
||||||
|
Image.Height,
|
||||||
|
Image.Depth,
|
||||||
|
Border,
|
||||||
|
PixelFormat,
|
||||||
|
PixelType,
|
||||||
|
IntPtr.Zero);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException(Target.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
if (Initialized)
|
if (Initialized)
|
||||||
{
|
{
|
||||||
|
|
|
@ -299,5 +299,17 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
|
|
||||||
throw new ArgumentException(nameof(BlendFactor));
|
throw new ArgumentException(nameof(BlendFactor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TextureTarget GetImageTarget(GalImageTarget Target)
|
||||||
|
{
|
||||||
|
switch (Target)
|
||||||
|
{
|
||||||
|
case GalImageTarget._2d: return TextureTarget.Texture2D;
|
||||||
|
case GalImageTarget._2dArray: return TextureTarget.Texture2DArray;
|
||||||
|
case GalImageTarget.CubeMap: return TextureTarget.TextureCubeMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new NotImplementedException(Target.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,7 +173,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
RawTex = new ImageHandler();
|
RawTex = new ImageHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
RawTex.EnsureSetup(new GalImage(Width, Height, RawFormat));
|
RawTex.EnsureSetup(new GalImage(Width, Height, 1, RawFormat, GalImageTarget._2d));
|
||||||
|
|
||||||
GL.BindTexture(TextureTarget.Texture2D, RawTex.Handle);
|
GL.BindTexture(TextureTarget.Texture2D, RawTex.Handle);
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
|
|
||||||
TextureCache.AddOrUpdate(Key, new ImageHandler(Handle, Image), (uint)Data.Length);
|
TextureCache.AddOrUpdate(Key, new ImageHandler(Handle, Image), (uint)Data.Length);
|
||||||
|
|
||||||
GL.BindTexture(TextureTarget.Texture2D, Handle);
|
TextureTarget Target = OGLEnumConverter.GetImageTarget(Image.Target);
|
||||||
|
|
||||||
|
GL.BindTexture(Target, Handle);
|
||||||
|
|
||||||
const int Level = 0; //TODO: Support mipmap textures.
|
const int Level = 0; //TODO: Support mipmap textures.
|
||||||
const int Border = 0;
|
const int Border = 0;
|
||||||
|
@ -43,21 +45,67 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
{
|
{
|
||||||
InternalFormat InternalFmt = OGLEnumConverter.GetCompressedImageFormat(Image.Format);
|
InternalFormat InternalFmt = OGLEnumConverter.GetCompressedImageFormat(Image.Format);
|
||||||
|
|
||||||
GL.CompressedTexImage2D(
|
switch (Target)
|
||||||
TextureTarget.Texture2D,
|
{
|
||||||
Level,
|
case TextureTarget.Texture2D:
|
||||||
InternalFmt,
|
GL.CompressedTexImage2D(
|
||||||
Image.Width,
|
Target,
|
||||||
Image.Height,
|
Level,
|
||||||
Border,
|
InternalFmt,
|
||||||
Data.Length,
|
Image.Width,
|
||||||
Data);
|
Image.Height,
|
||||||
|
Border,
|
||||||
|
Data.Length,
|
||||||
|
Data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TextureTarget.Texture2DArray:
|
||||||
|
GL.CompressedTexImage3D(
|
||||||
|
Target,
|
||||||
|
Level,
|
||||||
|
InternalFmt,
|
||||||
|
Image.Width,
|
||||||
|
Image.Height,
|
||||||
|
Image.Depth,
|
||||||
|
Border,
|
||||||
|
Data.Length,
|
||||||
|
Data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TextureTarget.TextureCubeMap:
|
||||||
|
{
|
||||||
|
int FaceSize = Data.Length / 6;
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
fixed (byte* DataPtr = Data)
|
||||||
|
{
|
||||||
|
GL.CompressedTexImage2D(
|
||||||
|
TextureTarget.TextureCubeMapPositiveX + i,
|
||||||
|
Level,
|
||||||
|
InternalFmt,
|
||||||
|
Image.Width,
|
||||||
|
Image.Height,
|
||||||
|
Border,
|
||||||
|
FaceSize,
|
||||||
|
(IntPtr)(DataPtr + FaceSize * i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException(Target.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Image.Format >= GalImageFormat.ASTC_BEGIN && Image.Format <= GalImageFormat.ASTC_END)
|
if (Image.Format >= GalImageFormat.ASTC_BEGIN && Image.Format <= GalImageFormat.ASTC_END)
|
||||||
{
|
{
|
||||||
int TextureBlockWidth = GetAstcBlockWidth(Image.Format);
|
int TextureBlockWidth = GetAstcBlockWidth(Image.Format);
|
||||||
int TextureBlockHeight = GetAstcBlockHeight(Image.Format);
|
int TextureBlockHeight = GetAstcBlockHeight(Image.Format);
|
||||||
|
|
||||||
Data = ASTCDecoder.DecodeToRGBA8888(
|
Data = ASTCDecoder.DecodeToRGBA8888(
|
||||||
|
@ -72,16 +120,64 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
|
|
||||||
(PixelInternalFormat InternalFormat, PixelFormat Format, PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format);
|
(PixelInternalFormat InternalFormat, PixelFormat Format, PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format);
|
||||||
|
|
||||||
GL.TexImage2D(
|
switch (Target)
|
||||||
TextureTarget.Texture2D,
|
{
|
||||||
Level,
|
case TextureTarget.Texture2D:
|
||||||
InternalFormat,
|
GL.TexImage2D(
|
||||||
Image.Width,
|
Target,
|
||||||
Image.Height,
|
Level,
|
||||||
Border,
|
InternalFormat,
|
||||||
Format,
|
Image.Width,
|
||||||
Type,
|
Image.Height,
|
||||||
Data);
|
Border,
|
||||||
|
Format,
|
||||||
|
Type,
|
||||||
|
Data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TextureTarget.TextureCubeMap:
|
||||||
|
{
|
||||||
|
long FaceSize = Data.LongLength / 6;
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
fixed (byte* DataPtr = Data)
|
||||||
|
{
|
||||||
|
GL.TexImage2D(
|
||||||
|
TextureTarget.TextureCubeMapPositiveX + i,
|
||||||
|
Level,
|
||||||
|
InternalFormat,
|
||||||
|
Image.Width,
|
||||||
|
Image.Height,
|
||||||
|
Border,
|
||||||
|
Format,
|
||||||
|
Type,
|
||||||
|
(IntPtr)(DataPtr + FaceSize * i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TextureTarget.Texture2DArray:
|
||||||
|
GL.TexImage3D(
|
||||||
|
Target,
|
||||||
|
Level,
|
||||||
|
InternalFormat,
|
||||||
|
Image.Width,
|
||||||
|
Image.Height,
|
||||||
|
Image.Depth,
|
||||||
|
Border,
|
||||||
|
Format,
|
||||||
|
Type,
|
||||||
|
Data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException(Target.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int SwizzleR = (int)OGLEnumConverter.GetTextureSwizzle(Image.XSource);
|
int SwizzleR = (int)OGLEnumConverter.GetTextureSwizzle(Image.XSource);
|
||||||
|
@ -89,10 +185,10 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
int SwizzleB = (int)OGLEnumConverter.GetTextureSwizzle(Image.ZSource);
|
int SwizzleB = (int)OGLEnumConverter.GetTextureSwizzle(Image.ZSource);
|
||||||
int SwizzleA = (int)OGLEnumConverter.GetTextureSwizzle(Image.WSource);
|
int SwizzleA = (int)OGLEnumConverter.GetTextureSwizzle(Image.WSource);
|
||||||
|
|
||||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleR, SwizzleR);
|
GL.TexParameter(Target, TextureParameterName.TextureSwizzleR, SwizzleR);
|
||||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleG, SwizzleG);
|
GL.TexParameter(Target, TextureParameterName.TextureSwizzleG, SwizzleG);
|
||||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleB, SwizzleB);
|
GL.TexParameter(Target, TextureParameterName.TextureSwizzleB, SwizzleB);
|
||||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleA, SwizzleA);
|
GL.TexParameter(Target, TextureParameterName.TextureSwizzleA, SwizzleA);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CreateFb(long Key, long Size, GalImage Image)
|
public void CreateFb(long Key, long Size, GalImage Image)
|
||||||
|
@ -186,25 +282,34 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
{
|
{
|
||||||
if (TextureCache.TryGetValue(Key, out ImageHandler CachedImage))
|
if (TextureCache.TryGetValue(Key, out ImageHandler CachedImage))
|
||||||
{
|
{
|
||||||
|
TextureTarget Target = OGLEnumConverter.GetImageTarget(CachedImage.Image.Target);
|
||||||
|
|
||||||
GL.ActiveTexture(TextureUnit.Texture0 + Index);
|
GL.ActiveTexture(TextureUnit.Texture0 + Index);
|
||||||
|
|
||||||
GL.BindTexture(TextureTarget.Texture2D, CachedImage.Handle);
|
GL.BindTexture(Target, CachedImage.Handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetSampler(GalTextureSampler Sampler)
|
public void SetSampler(long Key, GalTextureSampler Sampler)
|
||||||
{
|
{
|
||||||
|
if (!TextureCache.TryGetValue(Key, out ImageHandler CachedImage))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureTarget Target = OGLEnumConverter.GetImageTarget(CachedImage.Image.Target);
|
||||||
|
|
||||||
int WrapS = (int)OGLEnumConverter.GetTextureWrapMode(Sampler.AddressU);
|
int WrapS = (int)OGLEnumConverter.GetTextureWrapMode(Sampler.AddressU);
|
||||||
int WrapT = (int)OGLEnumConverter.GetTextureWrapMode(Sampler.AddressV);
|
int WrapT = (int)OGLEnumConverter.GetTextureWrapMode(Sampler.AddressV);
|
||||||
|
|
||||||
int MinFilter = (int)OGLEnumConverter.GetTextureMinFilter(Sampler.MinFilter, Sampler.MipFilter);
|
int MinFilter = (int)OGLEnumConverter.GetTextureMinFilter(Sampler.MinFilter, Sampler.MipFilter);
|
||||||
int MagFilter = (int)OGLEnumConverter.GetTextureMagFilter(Sampler.MagFilter);
|
int MagFilter = (int)OGLEnumConverter.GetTextureMagFilter(Sampler.MagFilter);
|
||||||
|
|
||||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, WrapS);
|
GL.TexParameter(Target, TextureParameterName.TextureWrapS, WrapS);
|
||||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, WrapT);
|
GL.TexParameter(Target, TextureParameterName.TextureWrapT, WrapT);
|
||||||
|
|
||||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, MinFilter);
|
GL.TexParameter(Target, TextureParameterName.TextureMinFilter, MinFilter);
|
||||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, MagFilter);
|
GL.TexParameter(Target, TextureParameterName.TextureMagFilter, MagFilter);
|
||||||
|
|
||||||
float[] Color = new float[]
|
float[] Color = new float[]
|
||||||
{
|
{
|
||||||
|
@ -214,7 +319,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
Sampler.BorderColor.Alpha
|
Sampler.BorderColor.Alpha
|
||||||
};
|
};
|
||||||
|
|
||||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBorderColor, Color);
|
GL.TexParameter(Target, TextureParameterName.TextureBorderColor, Color);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsCompressedTextureFormat(GalImageFormat Format)
|
private static bool IsCompressedTextureFormat(GalImageFormat Format)
|
||||||
|
|
|
@ -63,6 +63,8 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
private Dictionary<int, ShaderDeclInfo> m_Gprs;
|
private Dictionary<int, ShaderDeclInfo> m_Gprs;
|
||||||
private Dictionary<int, ShaderDeclInfo> m_Preds;
|
private Dictionary<int, ShaderDeclInfo> m_Preds;
|
||||||
|
|
||||||
|
private Dictionary<int, ShaderTextureType> m_TextureTypes;
|
||||||
|
|
||||||
public IReadOnlyDictionary<ShaderIrOp, ShaderDeclInfo> CbTextures => m_CbTextures;
|
public IReadOnlyDictionary<ShaderIrOp, ShaderDeclInfo> CbTextures => m_CbTextures;
|
||||||
|
|
||||||
public IReadOnlyDictionary<int, ShaderDeclInfo> Textures => m_Textures;
|
public IReadOnlyDictionary<int, ShaderDeclInfo> Textures => m_Textures;
|
||||||
|
@ -75,6 +77,8 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
public IReadOnlyDictionary<int, ShaderDeclInfo> Gprs => m_Gprs;
|
public IReadOnlyDictionary<int, ShaderDeclInfo> Gprs => m_Gprs;
|
||||||
public IReadOnlyDictionary<int, ShaderDeclInfo> Preds => m_Preds;
|
public IReadOnlyDictionary<int, ShaderDeclInfo> Preds => m_Preds;
|
||||||
|
|
||||||
|
public IReadOnlyDictionary<int, ShaderTextureType> TextureTypes => m_TextureTypes;
|
||||||
|
|
||||||
public GalShaderType ShaderType { get; private set; }
|
public GalShaderType ShaderType { get; private set; }
|
||||||
|
|
||||||
private GlslDecl(GalShaderType ShaderType)
|
private GlslDecl(GalShaderType ShaderType)
|
||||||
|
@ -92,6 +96,8 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
|
|
||||||
m_Gprs = new Dictionary<int, ShaderDeclInfo>();
|
m_Gprs = new Dictionary<int, ShaderDeclInfo>();
|
||||||
m_Preds = new Dictionary<int, ShaderDeclInfo>();
|
m_Preds = new Dictionary<int, ShaderDeclInfo>();
|
||||||
|
|
||||||
|
m_TextureTypes = new Dictionary<int, ShaderTextureType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlslDecl(ShaderIrBlock[] Blocks, GalShaderType ShaderType, ShaderHeader Header)
|
public GlslDecl(ShaderIrBlock[] Blocks, GalShaderType ShaderType, ShaderHeader Header)
|
||||||
|
@ -221,16 +227,26 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
Op.Inst == ShaderIrInst.Texs ||
|
Op.Inst == ShaderIrInst.Texs ||
|
||||||
Op.Inst == ShaderIrInst.Txlf)
|
Op.Inst == ShaderIrInst.Txlf)
|
||||||
{
|
{
|
||||||
int Handle = ((ShaderIrOperImm)Op.OperandC).Value;
|
ShaderIrMetaTex Meta = (ShaderIrMetaTex)Op.MetaData;
|
||||||
|
|
||||||
|
Traverse(Nodes, Op, Meta.Index);
|
||||||
|
|
||||||
|
int Handle = ((ShaderIrOperImm)Meta.Index).Value;
|
||||||
|
|
||||||
int Index = Handle - TexStartIndex;
|
int Index = Handle - TexStartIndex;
|
||||||
|
|
||||||
string Name = StagePrefix + TextureName + Index;
|
string Name = StagePrefix + TextureName + Index;
|
||||||
|
|
||||||
m_Textures.TryAdd(Handle, new ShaderDeclInfo(Name, Handle));
|
m_Textures.TryAdd(Handle, new ShaderDeclInfo(Name, Handle));
|
||||||
|
|
||||||
|
m_TextureTypes.TryAdd(Handle, Meta.Type);
|
||||||
}
|
}
|
||||||
else if (Op.Inst == ShaderIrInst.Texb)
|
else if (Op.Inst == ShaderIrInst.Texb)
|
||||||
{
|
{
|
||||||
|
ShaderIrMetaTex Meta = (ShaderIrMetaTex)Op.MetaData;
|
||||||
|
|
||||||
|
Traverse(Nodes, Op, Meta.Index);
|
||||||
|
|
||||||
ShaderIrNode HandleSrc = null;
|
ShaderIrNode HandleSrc = null;
|
||||||
|
|
||||||
int Index = Array.IndexOf(Nodes, Parent) - 1;
|
int Index = Array.IndexOf(Nodes, Parent) - 1;
|
||||||
|
@ -241,7 +257,7 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
|
|
||||||
if (Curr is ShaderIrAsg Asg && Asg.Dst is ShaderIrOperGpr Gpr)
|
if (Curr is ShaderIrAsg Asg && Asg.Dst is ShaderIrOperGpr Gpr)
|
||||||
{
|
{
|
||||||
if (Gpr.Index == ((ShaderIrOperGpr)Op.OperandC).Index)
|
if (Gpr.Index == ((ShaderIrOperGpr)Meta.Index).Index)
|
||||||
{
|
{
|
||||||
HandleSrc = Asg.Src;
|
HandleSrc = Asg.Src;
|
||||||
|
|
||||||
|
@ -255,6 +271,8 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
string Name = StagePrefix + TextureName + "_cb" + Cbuf.Index + "_" + Cbuf.Pos;
|
string Name = StagePrefix + TextureName + "_cb" + Cbuf.Index + "_" + Cbuf.Pos;
|
||||||
|
|
||||||
m_CbTextures.Add(Op, new ShaderDeclInfo(Name, Cbuf.Pos, true, Cbuf.Index));
|
m_CbTextures.Add(Op, new ShaderDeclInfo(Name, Cbuf.Pos, true, Cbuf.Index));
|
||||||
|
|
||||||
|
//TODO: Add m_CbTextures to texture types
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -221,7 +221,16 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
SB.AppendLine("uniform sampler2D " + DeclInfo.Name + ";");
|
SB.AppendLine("uniform sampler2D " + DeclInfo.Name + ";");
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintDecls(Decl.Textures, "uniform sampler2D");
|
foreach (ShaderDeclInfo DeclInfo in Decl.Textures.Values.OrderBy(DeclKeySelector))
|
||||||
|
{
|
||||||
|
ShaderTextureType Type = Decl.TextureTypes[DeclInfo.Index];
|
||||||
|
|
||||||
|
string TypeName = GetSamplerName(Type);
|
||||||
|
|
||||||
|
SB.AppendLine("uniform " + TypeName + " " + DeclInfo.Name + ";");
|
||||||
|
}
|
||||||
|
|
||||||
|
SB.AppendLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<ShaderDeclInfo> IterateCbTextures()
|
private IEnumerable<ShaderDeclInfo> IterateCbTextures()
|
||||||
|
@ -1188,9 +1197,9 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
|
|
||||||
private string GetTexSamplerName(ShaderIrOp Op)
|
private string GetTexSamplerName(ShaderIrOp Op)
|
||||||
{
|
{
|
||||||
ShaderIrOperImm Node = (ShaderIrOperImm)Op.OperandC;
|
ShaderIrNode Node = ((ShaderIrMetaTex)Op.MetaData).Index;
|
||||||
|
|
||||||
int Handle = ((ShaderIrOperImm)Op.OperandC).Value;
|
int Handle = ((ShaderIrOperImm)Node).Value;
|
||||||
|
|
||||||
if (!Decl.Textures.TryGetValue(Handle, out ShaderDeclInfo DeclInfo))
|
if (!Decl.Textures.TryGetValue(Handle, out ShaderDeclInfo DeclInfo))
|
||||||
{
|
{
|
||||||
|
@ -1202,14 +1211,32 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
|
|
||||||
private string GetTexSamplerCoords(ShaderIrOp Op)
|
private string GetTexSamplerCoords(ShaderIrOp Op)
|
||||||
{
|
{
|
||||||
return "vec2(" + GetOperExpr(Op, Op.OperandA) + ", " +
|
if (Op.OperandC != null)
|
||||||
GetOperExpr(Op, Op.OperandB) + ")";
|
{
|
||||||
|
return "vec3(" + GetOperExpr(Op, Op.OperandA) + ", " +
|
||||||
|
GetOperExpr(Op, Op.OperandB) + ", " +
|
||||||
|
GetOperExpr(Op, Op.OperandC) + ")";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "vec2(" + GetOperExpr(Op, Op.OperandA) + ", " +
|
||||||
|
GetOperExpr(Op, Op.OperandB) + ")";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetITexSamplerCoords(ShaderIrOp Op)
|
private string GetITexSamplerCoords(ShaderIrOp Op)
|
||||||
{
|
{
|
||||||
return "ivec2(" + GetOperExpr(Op, Op.OperandA) + ", " +
|
if (Op.OperandC != null)
|
||||||
GetOperExpr(Op, Op.OperandB) + ")";
|
{
|
||||||
|
return "ivec3(" + GetOperExpr(Op, Op.OperandA) + ", " +
|
||||||
|
GetOperExpr(Op, Op.OperandB) + ", " +
|
||||||
|
GetOperExpr(Op, Op.OperandC) + ")";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "ivec2(" + GetOperExpr(Op, Op.OperandA) + ", " +
|
||||||
|
GetOperExpr(Op, Op.OperandB) + ")";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetOperExpr(ShaderIrOp Op, ShaderIrNode Oper)
|
private string GetOperExpr(ShaderIrOp Op, ShaderIrNode Oper)
|
||||||
|
@ -1351,5 +1378,17 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
|
|
||||||
throw new ArgumentException(nameof(Node));
|
throw new ArgumentException(nameof(Node));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string GetSamplerName(ShaderTextureType Type)
|
||||||
|
{
|
||||||
|
switch (Type)
|
||||||
|
{
|
||||||
|
case ShaderTextureType._2d: return "sampler2D";
|
||||||
|
case ShaderTextureType._2dArray: return "sampler2DArray";
|
||||||
|
case ShaderTextureType.Cube: return "samplerCube";
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new NotImplementedException(Type.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,13 +31,28 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
{ RGB_, RG_A, R_BA, _GBA, RGBA, ____, ____, ____ }
|
{ RGB_, RG_A, R_BA, _GBA, RGBA, ____, ____, ____ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static ShaderTextureType[] TexsTypes = new ShaderTextureType[]
|
||||||
|
{
|
||||||
|
ShaderTextureType._1d,
|
||||||
|
ShaderTextureType._2d,
|
||||||
|
ShaderTextureType._2d,
|
||||||
|
ShaderTextureType._2d,
|
||||||
|
ShaderTextureType._2d,
|
||||||
|
ShaderTextureType._2d,
|
||||||
|
ShaderTextureType._2d,
|
||||||
|
ShaderTextureType._2dArray,
|
||||||
|
ShaderTextureType._2dArray,
|
||||||
|
ShaderTextureType._2dArray,
|
||||||
|
ShaderTextureType._3d,
|
||||||
|
ShaderTextureType._3d,
|
||||||
|
ShaderTextureType.Cube,
|
||||||
|
ShaderTextureType.Cube,
|
||||||
|
};
|
||||||
|
|
||||||
public static void Ld_A(ShaderIrBlock Block, long OpCode)
|
public static void Ld_A(ShaderIrBlock Block, long OpCode)
|
||||||
{
|
{
|
||||||
ShaderIrNode[] Opers = GetOperAbuf20(OpCode);
|
ShaderIrNode[] Opers = GetOperAbuf20(OpCode);
|
||||||
|
|
||||||
//Used by GS
|
|
||||||
ShaderIrOperGpr Vertex = GetOperGpr39(OpCode);
|
|
||||||
|
|
||||||
int Index = 0;
|
int Index = 0;
|
||||||
|
|
||||||
foreach (ShaderIrNode OperA in Opers)
|
foreach (ShaderIrNode OperA in Opers)
|
||||||
|
@ -118,15 +133,15 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
ShaderIrNode OperD = GetOperGpr0(OpCode);
|
ShaderIrNode OperD = GetOperGpr0(OpCode);
|
||||||
ShaderIrNode OperA = GetOperGpr8(OpCode);
|
ShaderIrNode OperA = GetOperGpr8(OpCode);
|
||||||
|
|
||||||
|
ShaderIrNode TextureIndex = GetOperImm13_36(OpCode);
|
||||||
|
|
||||||
ShaderTexqInfo Info = (ShaderTexqInfo)((OpCode >> 22) & 0x1f);
|
ShaderTexqInfo Info = (ShaderTexqInfo)((OpCode >> 22) & 0x1f);
|
||||||
|
|
||||||
ShaderIrMetaTexq Meta0 = new ShaderIrMetaTexq(Info, 0);
|
ShaderIrMetaTexq Meta0 = new ShaderIrMetaTexq(Info, ShaderTextureType._2d, TextureIndex, 0);
|
||||||
ShaderIrMetaTexq Meta1 = new ShaderIrMetaTexq(Info, 1);
|
ShaderIrMetaTexq Meta1 = new ShaderIrMetaTexq(Info, ShaderTextureType._2d, TextureIndex, 1);
|
||||||
|
|
||||||
ShaderIrNode OperC = GetOperImm13_36(OpCode);
|
ShaderIrOp Op0 = new ShaderIrOp(ShaderIrInst.Texq, OperA, null, null, Meta0);
|
||||||
|
ShaderIrOp Op1 = new ShaderIrOp(ShaderIrInst.Texq, OperA, null, null, Meta1);
|
||||||
ShaderIrOp Op0 = new ShaderIrOp(ShaderIrInst.Texq, OperA, null, OperC, Meta0);
|
|
||||||
ShaderIrOp Op1 = new ShaderIrOp(ShaderIrInst.Texq, OperA, null, OperC, Meta1);
|
|
||||||
|
|
||||||
Block.AddNode(GetPredNode(new ShaderIrAsg(OperD, Op0), OpCode));
|
Block.AddNode(GetPredNode(new ShaderIrAsg(OperD, Op0), OpCode));
|
||||||
Block.AddNode(GetPredNode(new ShaderIrAsg(OperA, Op1), OpCode)); //Is this right?
|
Block.AddNode(GetPredNode(new ShaderIrAsg(OperA, Op1), OpCode)); //Is this right?
|
||||||
|
@ -161,7 +176,7 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
|
|
||||||
int ChMask = (int)(OpCode >> 31) & 0xf;
|
int ChMask = (int)(OpCode >> 31) & 0xf;
|
||||||
|
|
||||||
ShaderIrNode OperC = GprHandle
|
ShaderIrNode TextureIndex = GprHandle
|
||||||
? (ShaderIrNode)GetOperGpr20 (OpCode)
|
? (ShaderIrNode)GetOperGpr20 (OpCode)
|
||||||
: (ShaderIrNode)GetOperImm13_36(OpCode);
|
: (ShaderIrNode)GetOperImm13_36(OpCode);
|
||||||
|
|
||||||
|
@ -171,9 +186,9 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
{
|
{
|
||||||
ShaderIrOperGpr Dst = new ShaderIrOperGpr(TempRegStart + Ch);
|
ShaderIrOperGpr Dst = new ShaderIrOperGpr(TempRegStart + Ch);
|
||||||
|
|
||||||
ShaderIrMetaTex Meta = new ShaderIrMetaTex(Ch);
|
ShaderIrMetaTex Meta = new ShaderIrMetaTex(ShaderTextureType._2d, TextureIndex, Ch);
|
||||||
|
|
||||||
ShaderIrOp Op = new ShaderIrOp(Inst, Coords[0], Coords[1], OperC, Meta);
|
ShaderIrOp Op = new ShaderIrOp(Inst, Coords[0], Coords[1], null, Meta);
|
||||||
|
|
||||||
Block.AddNode(GetPredNode(new ShaderIrAsg(Dst, Op), OpCode));
|
Block.AddNode(GetPredNode(new ShaderIrAsg(Dst, Op), OpCode));
|
||||||
}
|
}
|
||||||
|
@ -214,10 +229,7 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
|
|
||||||
private static void EmitTexs(ShaderIrBlock Block, long OpCode, ShaderIrInst Inst)
|
private static void EmitTexs(ShaderIrBlock Block, long OpCode, ShaderIrInst Inst)
|
||||||
{
|
{
|
||||||
//TODO: Support other formats.
|
ShaderIrNode TextureIndex = GetOperImm13_36(OpCode);
|
||||||
ShaderIrNode OperA = GetOperGpr8 (OpCode);
|
|
||||||
ShaderIrNode OperB = GetOperGpr20 (OpCode);
|
|
||||||
ShaderIrNode OperC = GetOperImm13_36(OpCode);
|
|
||||||
|
|
||||||
int LutIndex;
|
int LutIndex;
|
||||||
|
|
||||||
|
@ -233,11 +245,44 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
|
|
||||||
int ChMask = MaskLut[LutIndex, (OpCode >> 50) & 7];
|
int ChMask = MaskLut[LutIndex, (OpCode >> 50) & 7];
|
||||||
|
|
||||||
|
long TypeIndex = (OpCode >> 53) & 0xf;
|
||||||
|
|
||||||
|
ShaderTextureType Type = TexsTypes[TypeIndex];
|
||||||
|
|
||||||
|
ShaderIrNode OperA = null;
|
||||||
|
ShaderIrNode OperB = null;
|
||||||
|
ShaderIrNode OperC = null;
|
||||||
|
|
||||||
|
switch (Type)
|
||||||
|
{
|
||||||
|
case ShaderTextureType._2d:
|
||||||
|
OperA = GetOperGpr8 (OpCode);
|
||||||
|
OperB = GetOperGpr20(OpCode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
//Unsure about this layout
|
||||||
|
case ShaderTextureType._2dArray:
|
||||||
|
OperA = GetOperGpr8 (OpCode) + 1;
|
||||||
|
OperB = GetOperGpr20(OpCode);
|
||||||
|
OperC = GetOperGpr8 (OpCode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
//Unsure about this layout
|
||||||
|
case ShaderTextureType.Cube:
|
||||||
|
OperA = GetOperGpr8 (OpCode);
|
||||||
|
OperB = GetOperGpr8 (OpCode) + 1;
|
||||||
|
OperC = GetOperGpr20(OpCode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException(Type.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
for (int Ch = 0; Ch < 4; Ch++)
|
for (int Ch = 0; Ch < 4; Ch++)
|
||||||
{
|
{
|
||||||
ShaderIrOperGpr Dst = new ShaderIrOperGpr(TempRegStart + Ch);
|
ShaderIrOperGpr Dst = new ShaderIrOperGpr(TempRegStart + Ch);
|
||||||
|
|
||||||
ShaderIrMetaTex Meta = new ShaderIrMetaTex(Ch);
|
ShaderIrMetaTex Meta = new ShaderIrMetaTex(Type, TextureIndex, Ch);
|
||||||
|
|
||||||
ShaderIrOp Op = new ShaderIrOp(Inst, OperA, OperB, OperC, Meta);
|
ShaderIrOp Op = new ShaderIrOp(Inst, OperA, OperB, OperC, Meta);
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,17 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
{
|
{
|
||||||
class ShaderIrMetaTex : ShaderIrMeta
|
class ShaderIrMetaTex : ShaderIrMeta
|
||||||
{
|
{
|
||||||
|
public ShaderTextureType Type { get; private set; }
|
||||||
|
|
||||||
|
public ShaderIrNode Index { get; private set; }
|
||||||
|
|
||||||
public int Elem { get; private set; }
|
public int Elem { get; private set; }
|
||||||
|
|
||||||
public ShaderIrMetaTex(int Elem)
|
public ShaderIrMetaTex(ShaderTextureType Type, ShaderIrNode Index, int Elem)
|
||||||
{
|
{
|
||||||
this.Elem = Elem;
|
this.Type = Type;
|
||||||
|
this.Index = Index;
|
||||||
|
this.Elem = Elem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,15 +1,13 @@
|
||||||
namespace Ryujinx.Graphics.Gal.Shader
|
namespace Ryujinx.Graphics.Gal.Shader
|
||||||
{
|
{
|
||||||
class ShaderIrMetaTexq : ShaderIrMeta
|
class ShaderIrMetaTexq : ShaderIrMetaTex
|
||||||
{
|
{
|
||||||
public ShaderTexqInfo Info { get; private set; }
|
public ShaderTexqInfo Info { get; private set; }
|
||||||
|
|
||||||
public int Elem { get; private set; }
|
public ShaderIrMetaTexq(ShaderTexqInfo Info, ShaderTextureType Type, ShaderIrNode Index, int Elem)
|
||||||
|
: base(Type, Index, Elem)
|
||||||
public ShaderIrMetaTexq(ShaderTexqInfo Info, int Elem)
|
|
||||||
{
|
{
|
||||||
this.Info = Info;
|
this.Info = Info;
|
||||||
this.Elem = Elem;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -15,6 +15,11 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
this.Index = Index;
|
this.Index = Index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ShaderIrOperGpr operator+(ShaderIrOperGpr Gpr, int PlusIndex)
|
||||||
|
{
|
||||||
|
return new ShaderIrOperGpr(Gpr.Index + PlusIndex);
|
||||||
|
}
|
||||||
|
|
||||||
public static ShaderIrOperGpr MakeTemporary(int Index = 0)
|
public static ShaderIrOperGpr MakeTemporary(int Index = 0)
|
||||||
{
|
{
|
||||||
return new ShaderIrOperGpr(0x100 + Index);
|
return new ShaderIrOperGpr(0x100 + Index);
|
||||||
|
|
11
Ryujinx.Graphics/Gal/Shader/ShaderTextureType.cs
Normal file
11
Ryujinx.Graphics/Gal/Shader/ShaderTextureType.cs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
namespace Ryujinx.Graphics.Gal.Shader
|
||||||
|
{
|
||||||
|
enum ShaderTextureType
|
||||||
|
{
|
||||||
|
_1d,
|
||||||
|
_2d,
|
||||||
|
_2dArray,
|
||||||
|
_3d,
|
||||||
|
Cube
|
||||||
|
}
|
||||||
|
}
|
|
@ -202,7 +202,7 @@ namespace Ryujinx.HLE.Gpu.Engines
|
||||||
|
|
||||||
GalImageFormat ImageFormat = ImageFormatConverter.ConvertFrameBuffer((GalFrameBufferFormat)Format);
|
GalImageFormat ImageFormat = ImageFormatConverter.ConvertFrameBuffer((GalFrameBufferFormat)Format);
|
||||||
|
|
||||||
GalImage Image = new GalImage(Width, Height, ImageFormat);
|
GalImage Image = new GalImage(Width, Height, 1, ImageFormat, GalImageTarget._2d);
|
||||||
|
|
||||||
long Size = TextureHelper.GetTextureSize(Image);
|
long Size = TextureHelper.GetTextureSize(Image);
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ namespace Ryujinx.HLE.Gpu.Engines
|
||||||
|
|
||||||
GalImageFormat ImageFormat = ImageFormatConverter.ConvertZeta((GalZetaFormat)Format);
|
GalImageFormat ImageFormat = ImageFormatConverter.ConvertZeta((GalZetaFormat)Format);
|
||||||
|
|
||||||
GalImage Image = new GalImage(Width, Height, ImageFormat);
|
GalImage Image = new GalImage(Width, Height, 1, ImageFormat, GalImageTarget._2d);
|
||||||
|
|
||||||
long Size = TextureHelper.GetTextureSize(Image);
|
long Size = TextureHelper.GetTextureSize(Image);
|
||||||
|
|
||||||
|
@ -549,7 +549,7 @@ namespace Ryujinx.HLE.Gpu.Engines
|
||||||
Gpu.Renderer.Texture.Bind(Key, TexIndex);
|
Gpu.Renderer.Texture.Bind(Key, TexIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
Gpu.Renderer.Texture.SetSampler(Sampler);
|
Gpu.Renderer.Texture.SetSampler(Key, Sampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UploadConstBuffers(NvGpuVmm Vmm, GalPipelineState State, long[] Keys)
|
private void UploadConstBuffers(NvGpuVmm Vmm, GalPipelineState State, long[] Keys)
|
||||||
|
|
|
@ -24,11 +24,16 @@ namespace Ryujinx.HLE.Gpu.Texture
|
||||||
|
|
||||||
int Width = (Tic[4] & 0xffff) + 1;
|
int Width = (Tic[4] & 0xffff) + 1;
|
||||||
int Height = (Tic[5] & 0xffff) + 1;
|
int Height = (Tic[5] & 0xffff) + 1;
|
||||||
|
int Depth = ((Tic[5] >> 16) & 0x7fff) + 1;
|
||||||
|
|
||||||
|
GalImageTarget Target = (GalImageTarget)((Tic[4] >> 23) & 0xf);
|
||||||
|
|
||||||
return new GalImage(
|
return new GalImage(
|
||||||
Width,
|
Width,
|
||||||
Height,
|
Height,
|
||||||
|
Depth,
|
||||||
Format,
|
Format,
|
||||||
|
Target,
|
||||||
XSource,
|
XSource,
|
||||||
YSource,
|
YSource,
|
||||||
ZSource,
|
ZSource,
|
||||||
|
|
Loading…
Reference in a new issue