Support depth in read/writeTexture
Also support WrapR and detect mipmap
This commit is contained in:
parent
f426de7e15
commit
5f0da0245e
13 changed files with 206 additions and 103 deletions
|
@ -10,6 +10,7 @@ namespace Ryujinx.Graphics.Gal
|
||||||
public int TileWidth;
|
public int TileWidth;
|
||||||
public int GobBlockHeight;
|
public int GobBlockHeight;
|
||||||
public int Pitch;
|
public int Pitch;
|
||||||
|
public int MaxMipmapLevel;
|
||||||
|
|
||||||
public GalImageFormat Format;
|
public GalImageFormat Format;
|
||||||
public GalMemoryLayout Layout;
|
public GalMemoryLayout Layout;
|
||||||
|
@ -28,10 +29,11 @@ namespace Ryujinx.Graphics.Gal
|
||||||
GalMemoryLayout Layout,
|
GalMemoryLayout Layout,
|
||||||
GalImageFormat Format,
|
GalImageFormat Format,
|
||||||
TextureType TextureType,
|
TextureType TextureType,
|
||||||
GalTextureSource XSource = GalTextureSource.Red,
|
int MaxMipmapLevel = 1,
|
||||||
GalTextureSource YSource = GalTextureSource.Green,
|
GalTextureSource XSource = GalTextureSource.Red,
|
||||||
GalTextureSource ZSource = GalTextureSource.Blue,
|
GalTextureSource YSource = GalTextureSource.Green,
|
||||||
GalTextureSource WSource = GalTextureSource.Alpha)
|
GalTextureSource ZSource = GalTextureSource.Blue,
|
||||||
|
GalTextureSource WSource = GalTextureSource.Alpha)
|
||||||
{
|
{
|
||||||
this.Width = Width;
|
this.Width = Width;
|
||||||
this.Height = Height;
|
this.Height = Height;
|
||||||
|
@ -40,6 +42,7 @@ namespace Ryujinx.Graphics.Gal
|
||||||
this.GobBlockHeight = GobBlockHeight;
|
this.GobBlockHeight = GobBlockHeight;
|
||||||
this.Layout = Layout;
|
this.Layout = Layout;
|
||||||
this.Format = Format;
|
this.Format = Format;
|
||||||
|
this.MaxMipmapLevel = MaxMipmapLevel;
|
||||||
this.XSource = XSource;
|
this.XSource = XSource;
|
||||||
this.YSource = YSource;
|
this.YSource = YSource;
|
||||||
this.ZSource = ZSource;
|
this.ZSource = ZSource;
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
|
|
||||||
public int Width => Image.Width;
|
public int Width => Image.Width;
|
||||||
public int Height => Image.Height;
|
public int Height => Image.Height;
|
||||||
|
public int Depth => Image.Depth;
|
||||||
|
|
||||||
public GalImageFormat Format => Image.Format;
|
public GalImageFormat Format => Image.Format;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ using OpenTK.Graphics.OpenGL;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.Texture;
|
using Ryujinx.Graphics.Texture;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gal.OpenGL
|
namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
{
|
{
|
||||||
|
@ -46,6 +47,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
const int Level = 0; //TODO: Support mipmap textures.
|
const int Level = 0; //TODO: Support mipmap textures.
|
||||||
const int Border = 0;
|
const int Border = 0;
|
||||||
|
|
||||||
|
Debug.Assert(Image.MaxMipmapLevel != 1, "No Mipmap support");
|
||||||
|
|
||||||
TextureCache.AddOrUpdate(Key, new ImageHandler(Handle, Image), (uint)Size);
|
TextureCache.AddOrUpdate(Key, new ImageHandler(Handle, Image), (uint)Size);
|
||||||
|
|
||||||
if (ImageUtils.IsCompressed(Image.Format))
|
if (ImageUtils.IsCompressed(Image.Format))
|
||||||
|
@ -87,7 +90,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Logger.PrintWarning(LogClass.Gpu, $"Unsupported texture target type: {Target}");
|
Logger.PrintWarning(LogClass.Gpu, $"Unsupported texture target type: {Target}");
|
||||||
//throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
GL.TexImage2D(
|
GL.TexImage2D(
|
||||||
TextureTarget.Texture2D,
|
TextureTarget.Texture2D,
|
||||||
Level,
|
Level,
|
||||||
|
@ -115,6 +118,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
const int Level = 0; //TODO: Support mipmap textures.
|
const int Level = 0; //TODO: Support mipmap textures.
|
||||||
const int Border = 0;
|
const int Border = 0;
|
||||||
|
|
||||||
|
Debug.Assert(Image.MaxMipmapLevel != 1, "No Mipmap support");
|
||||||
|
|
||||||
TextureCache.AddOrUpdate(Key, new ImageHandler(Handle, Image), (uint)Data.Length);
|
TextureCache.AddOrUpdate(Key, new ImageHandler(Handle, Image), (uint)Data.Length);
|
||||||
|
|
||||||
if (ImageUtils.IsCompressed(Image.Format) && !IsAstc(Image.Format))
|
if (ImageUtils.IsCompressed(Image.Format) && !IsAstc(Image.Format))
|
||||||
|
@ -195,14 +200,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
{
|
{
|
||||||
int TextureBlockWidth = ImageUtils.GetBlockWidth(Image.Format);
|
int TextureBlockWidth = ImageUtils.GetBlockWidth(Image.Format);
|
||||||
int TextureBlockHeight = ImageUtils.GetBlockHeight(Image.Format);
|
int TextureBlockHeight = ImageUtils.GetBlockHeight(Image.Format);
|
||||||
|
int TextureBlockDepth = ImageUtils.GetBlockDepth(Image.Format);
|
||||||
|
|
||||||
// TODO: support 3D textures
|
|
||||||
Data = ASTCDecoder.DecodeToRGBA8888(
|
Data = ASTCDecoder.DecodeToRGBA8888(
|
||||||
Data,
|
Data,
|
||||||
TextureBlockWidth,
|
TextureBlockWidth,
|
||||||
TextureBlockHeight, 1,
|
TextureBlockHeight,
|
||||||
|
TextureBlockDepth,
|
||||||
Image.Width,
|
Image.Width,
|
||||||
Image.Height, 1);
|
Image.Height,
|
||||||
|
Image.Depth);
|
||||||
|
|
||||||
Image.Format = GalImageFormat.RGBA8 | (Image.Format & GalImageFormat.TypeMask);
|
Image.Format = GalImageFormat.RGBA8 | (Image.Format & GalImageFormat.TypeMask);
|
||||||
}
|
}
|
||||||
|
@ -211,16 +218,50 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
PixelFormat Format,
|
PixelFormat Format,
|
||||||
PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format);
|
PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format);
|
||||||
|
|
||||||
GL.TexImage2D(
|
|
||||||
TextureTarget.Texture2D,
|
switch (Target)
|
||||||
Level,
|
{
|
||||||
InternalFmt,
|
case TextureTarget.Texture2D:
|
||||||
Image.Width,
|
GL.TexImage2D(
|
||||||
Image.Height,
|
Target,
|
||||||
Border,
|
Level,
|
||||||
Format,
|
InternalFmt,
|
||||||
Type,
|
Image.Width,
|
||||||
Data);
|
Image.Height,
|
||||||
|
Border,
|
||||||
|
Format,
|
||||||
|
Type,
|
||||||
|
Data);
|
||||||
|
break;
|
||||||
|
case TextureTarget.Texture2DArray:
|
||||||
|
case TextureTarget.Texture3D:
|
||||||
|
GL.TexImage3D(
|
||||||
|
Target,
|
||||||
|
Level,
|
||||||
|
InternalFmt,
|
||||||
|
Image.Width,
|
||||||
|
Image.Height,
|
||||||
|
Image.Depth,
|
||||||
|
Border,
|
||||||
|
Format,
|
||||||
|
Type,
|
||||||
|
Data);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Logger.PrintWarning(LogClass.Gpu, $"Unsupported texture target type: {Target}");
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
GL.TexImage2D(
|
||||||
|
TextureTarget.Texture2D,
|
||||||
|
Level,
|
||||||
|
InternalFmt,
|
||||||
|
Image.Width,
|
||||||
|
Image.Height,
|
||||||
|
Border,
|
||||||
|
Format,
|
||||||
|
Type,
|
||||||
|
Data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,6 +324,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
{
|
{
|
||||||
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 WrapR = (int)OGLEnumConverter.GetTextureWrapMode(Sampler.AddressP);
|
||||||
|
|
||||||
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);
|
||||||
|
@ -291,6 +333,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
|
|
||||||
GL.TexParameter(Target, TextureParameterName.TextureWrapS, WrapS);
|
GL.TexParameter(Target, TextureParameterName.TextureWrapS, WrapS);
|
||||||
GL.TexParameter(Target, TextureParameterName.TextureWrapT, WrapT);
|
GL.TexParameter(Target, TextureParameterName.TextureWrapT, WrapT);
|
||||||
|
GL.TexParameter(Target, TextureParameterName.TextureWrapR, WrapR);
|
||||||
|
|
||||||
GL.TexParameter(Target, TextureParameterName.TextureMinFilter, MinFilter);
|
GL.TexParameter(Target, TextureParameterName.TextureMinFilter, MinFilter);
|
||||||
GL.TexParameter(Target, TextureParameterName.TextureMagFilter, MagFilter);
|
GL.TexParameter(Target, TextureParameterName.TextureMagFilter, MagFilter);
|
||||||
|
|
|
@ -38,6 +38,7 @@ namespace Ryujinx.Graphics.Graphics3d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: SUPPORT NON 2D
|
||||||
private void TextureCopy(NvGpuVmm Vmm)
|
private void TextureCopy(NvGpuVmm Vmm)
|
||||||
{
|
{
|
||||||
CopyOperation Operation = (CopyOperation)ReadRegister(NvGpuEngine2dReg.CopyOperation);
|
CopyOperation Operation = (CopyOperation)ReadRegister(NvGpuEngine2dReg.CopyOperation);
|
||||||
|
@ -82,8 +83,6 @@ namespace Ryujinx.Graphics.Graphics3d
|
||||||
long SrcKey = Vmm.GetPhysicalAddress(SrcAddress);
|
long SrcKey = Vmm.GetPhysicalAddress(SrcAddress);
|
||||||
long DstKey = Vmm.GetPhysicalAddress(DstAddress);
|
long DstKey = Vmm.GetPhysicalAddress(DstAddress);
|
||||||
|
|
||||||
// TODO: all texture types
|
|
||||||
|
|
||||||
GalImage SrcTexture = new GalImage(
|
GalImage SrcTexture = new GalImage(
|
||||||
SrcWidth,
|
SrcWidth,
|
||||||
SrcHeight, 1, 1,
|
SrcHeight, 1, 1,
|
||||||
|
|
|
@ -125,29 +125,29 @@ namespace Ryujinx.Graphics.Graphics3d
|
||||||
|
|
||||||
if (SrcLinear)
|
if (SrcLinear)
|
||||||
{
|
{
|
||||||
SrcSwizzle = new LinearSwizzle(SrcPitch, SrcCpp);
|
SrcSwizzle = new LinearSwizzle(SrcPitch, SrcCpp, SrcSizeX, SrcSizeY);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SrcSwizzle = new BlockLinearSwizzle(SrcSizeX, SrcCpp, SrcBlockHeight);
|
SrcSwizzle = new BlockLinearSwizzle(SrcSizeX, SrcSizeY, SrcCpp, SrcBlockHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
ISwizzle DstSwizzle;
|
ISwizzle DstSwizzle;
|
||||||
|
|
||||||
if (DstLinear)
|
if (DstLinear)
|
||||||
{
|
{
|
||||||
DstSwizzle = new LinearSwizzle(DstPitch, DstCpp);
|
DstSwizzle = new LinearSwizzle(DstPitch, DstCpp, SrcSizeX, SrcSizeY);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DstSwizzle = new BlockLinearSwizzle(DstSizeX, DstCpp, DstBlockHeight);
|
DstSwizzle = new BlockLinearSwizzle(DstSizeX, DstSizeY, DstCpp, DstBlockHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int Y = 0; Y < YCount; Y++)
|
for (int Y = 0; Y < YCount; Y++)
|
||||||
for (int X = 0; X < XCount; X++)
|
for (int X = 0; X < XCount; X++)
|
||||||
{
|
{
|
||||||
int SrcOffset = SrcSwizzle.GetSwizzleOffset(SrcPosX + X, SrcPosY + Y);
|
int SrcOffset = SrcSwizzle.GetSwizzleOffset(SrcPosX + X, SrcPosY + Y, 0);
|
||||||
int DstOffset = DstSwizzle.GetSwizzleOffset(DstPosX + X, DstPosY + Y);
|
int DstOffset = DstSwizzle.GetSwizzleOffset(DstPosX + X, DstPosY + Y, 0);
|
||||||
|
|
||||||
long Src = SrcPA + (uint)SrcOffset;
|
long Src = SrcPA + (uint)SrcOffset;
|
||||||
long Dst = DstPA + (uint)DstOffset;
|
long Dst = DstPA + (uint)DstOffset;
|
||||||
|
|
|
@ -119,14 +119,14 @@ namespace Ryujinx.Graphics.Graphics3d
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BlockLinearSwizzle Swizzle = new BlockLinearSwizzle(CopyWidth, 1, CopyGobBlockHeight);
|
BlockLinearSwizzle Swizzle = new BlockLinearSwizzle(CopyWidth, CopyHeight, 1, CopyGobBlockHeight);
|
||||||
|
|
||||||
int SrcOffset = 0;
|
int SrcOffset = 0;
|
||||||
|
|
||||||
for (int Y = CopyStartY; Y < CopyHeight && SrcOffset < CopySize; Y++)
|
for (int Y = CopyStartY; Y < CopyHeight && SrcOffset < CopySize; Y++)
|
||||||
for (int X = CopyStartX; X < CopyWidth && SrcOffset < CopySize; X++)
|
for (int X = CopyStartX; X < CopyWidth && SrcOffset < CopySize; X++)
|
||||||
{
|
{
|
||||||
int DstOffset = Swizzle.GetSwizzleOffset(X, Y);
|
int DstOffset = Swizzle.GetSwizzleOffset(X, Y, 0);
|
||||||
|
|
||||||
Vmm.WriteByte(CopyAddress + DstOffset, Buffer[SrcOffset++]);
|
Vmm.WriteByte(CopyAddress + DstOffset, Buffer[SrcOffset++]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
|
|
||||||
if (BlockZ != 1 || Z != 1)
|
if (BlockZ != 1 || Z != 1)
|
||||||
{
|
{
|
||||||
|
// TODO: support 3D textures?
|
||||||
throw new ASTCDecoderException("3D compressed textures unsupported!");
|
throw new ASTCDecoderException("3D compressed textures unsupported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,9 @@ namespace Ryujinx.Graphics.Texture
|
||||||
private int XShift;
|
private int XShift;
|
||||||
private int GobStride;
|
private int GobStride;
|
||||||
|
|
||||||
public BlockLinearSwizzle(int Width, int Bpp, int BlockHeight = 16)
|
private int LayerZ;
|
||||||
|
|
||||||
|
public BlockLinearSwizzle(int Width, int Height, int Bpp, int BlockHeight)
|
||||||
{
|
{
|
||||||
BhMask = (BlockHeight * 8) - 1;
|
BhMask = (BlockHeight * 8) - 1;
|
||||||
|
|
||||||
|
@ -23,6 +25,8 @@ namespace Ryujinx.Graphics.Texture
|
||||||
GobStride = 512 * BlockHeight * WidthInGobs;
|
GobStride = 512 * BlockHeight * WidthInGobs;
|
||||||
|
|
||||||
XShift = CountLsbZeros(512 * BlockHeight);
|
XShift = CountLsbZeros(512 * BlockHeight);
|
||||||
|
|
||||||
|
LayerZ = Bpp * Width * Height;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int CountLsbZeros(int Value)
|
private int CountLsbZeros(int Value)
|
||||||
|
@ -37,7 +41,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return Count;
|
return Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetSwizzleOffset(int X, int Y)
|
public int GetSwizzleOffset(int X, int Y, int Z)
|
||||||
{
|
{
|
||||||
X <<= BppShift;
|
X <<= BppShift;
|
||||||
|
|
||||||
|
@ -53,7 +57,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
Position += ((Y & 0x01) >> 0) << 4;
|
Position += ((Y & 0x01) >> 0) << 4;
|
||||||
Position += ((X & 0x0f) >> 0) << 0;
|
Position += ((X & 0x0f) >> 0) << 0;
|
||||||
|
|
||||||
return Position;
|
return (Z * LayerZ) + Position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,6 +2,6 @@ namespace Ryujinx.Graphics.Texture
|
||||||
{
|
{
|
||||||
interface ISwizzle
|
interface ISwizzle
|
||||||
{
|
{
|
||||||
int GetSwizzleOffset(int X, int Y);
|
int GetSwizzleOffset(int X, int Y, int Z);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,6 +4,7 @@ using Ryujinx.Graphics.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Texture
|
namespace Ryujinx.Graphics.Texture
|
||||||
{
|
{
|
||||||
|
@ -24,14 +25,16 @@ namespace Ryujinx.Graphics.Texture
|
||||||
public int BytesPerPixel { get; private set; }
|
public int BytesPerPixel { get; private set; }
|
||||||
public int BlockWidth { get; private set; }
|
public int BlockWidth { get; private set; }
|
||||||
public int BlockHeight { get; private set; }
|
public int BlockHeight { get; private set; }
|
||||||
|
public int BlockDepth { get; private set; }
|
||||||
|
|
||||||
public TargetBuffer Target { get; private set; }
|
public TargetBuffer Target { get; private set; }
|
||||||
|
|
||||||
public ImageDescriptor(int BytesPerPixel, int BlockWidth, int BlockHeight, TargetBuffer Target)
|
public ImageDescriptor(int BytesPerPixel, int BlockWidth, int BlockHeight, int BlockDepth, TargetBuffer Target)
|
||||||
{
|
{
|
||||||
this.BytesPerPixel = BytesPerPixel;
|
this.BytesPerPixel = BytesPerPixel;
|
||||||
this.BlockWidth = BlockWidth;
|
this.BlockWidth = BlockWidth;
|
||||||
this.BlockHeight = BlockHeight;
|
this.BlockHeight = BlockHeight;
|
||||||
|
this.BlockDepth = BlockDepth;
|
||||||
this.Target = Target;
|
this.Target = Target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,52 +96,53 @@ namespace Ryujinx.Graphics.Texture
|
||||||
private static readonly Dictionary<GalImageFormat, ImageDescriptor> s_ImageTable =
|
private static readonly Dictionary<GalImageFormat, ImageDescriptor> s_ImageTable =
|
||||||
new Dictionary<GalImageFormat, ImageDescriptor>()
|
new Dictionary<GalImageFormat, ImageDescriptor>()
|
||||||
{
|
{
|
||||||
{ GalImageFormat.RGBA32, new ImageDescriptor(16, 1, 1, TargetBuffer.Color) },
|
// TODO: check if everything is alright here
|
||||||
{ GalImageFormat.RGBA16, new ImageDescriptor(8, 1, 1, TargetBuffer.Color) },
|
{ GalImageFormat.RGBA32, new ImageDescriptor(16, 1, 1, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.RG32, new ImageDescriptor(8, 1, 1, TargetBuffer.Color) },
|
{ GalImageFormat.RGBA16, new ImageDescriptor(8, 1, 1, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.RGBX8, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
|
{ GalImageFormat.RG32, new ImageDescriptor(8, 1, 1, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.RGBA8, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
|
{ GalImageFormat.RGBX8, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.BGRA8, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
|
{ GalImageFormat.RGBA8, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.RGB10A2, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
|
{ GalImageFormat.BGRA8, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.R32, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
|
{ GalImageFormat.RGB10A2, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.RGBA4, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) },
|
{ GalImageFormat.R32, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.BptcSfloat, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
|
{ GalImageFormat.RGBA4, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.BptcUfloat, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
|
{ GalImageFormat.BptcSfloat, new ImageDescriptor(16, 4, 4, 4, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.BGR5A1, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) },
|
{ GalImageFormat.BptcUfloat, new ImageDescriptor(16, 4, 4, 4, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.RGB5A1, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) },
|
{ GalImageFormat.BGR5A1, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.RGB565, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) },
|
{ GalImageFormat.RGB5A1, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.BGR565, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) },
|
{ GalImageFormat.RGB565, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.BptcUnorm, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
|
{ GalImageFormat.BGR565, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.RG16, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
|
{ GalImageFormat.BptcUnorm, new ImageDescriptor(16, 4, 4, 4, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.RG8, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) },
|
{ GalImageFormat.RG16, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.R16, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) },
|
{ GalImageFormat.RG8, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.R8, new ImageDescriptor(1, 1, 1, TargetBuffer.Color) },
|
{ GalImageFormat.R16, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.R11G11B10, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
|
{ GalImageFormat.R8, new ImageDescriptor(1, 1, 1, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.BC1, new ImageDescriptor(8, 4, 4, TargetBuffer.Color) },
|
{ GalImageFormat.R11G11B10, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.BC2, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
|
{ GalImageFormat.BC1, new ImageDescriptor(8, 4, 4, 4, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.BC3, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
|
{ GalImageFormat.BC2, new ImageDescriptor(16, 4, 4, 4, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.BC4, new ImageDescriptor(8, 4, 4, TargetBuffer.Color) },
|
{ GalImageFormat.BC3, new ImageDescriptor(16, 4, 4, 4, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.BC5, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
|
{ GalImageFormat.BC4, new ImageDescriptor(8, 4, 4, 4, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.Astc2D4x4, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
|
{ GalImageFormat.BC5, new ImageDescriptor(16, 4, 4, 4, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.Astc2D5x5, new ImageDescriptor(16, 5, 5, TargetBuffer.Color) },
|
{ GalImageFormat.Astc2D4x4, new ImageDescriptor(16, 4, 4, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.Astc2D6x6, new ImageDescriptor(16, 6, 6, TargetBuffer.Color) },
|
{ GalImageFormat.Astc2D5x5, new ImageDescriptor(16, 5, 5, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.Astc2D8x8, new ImageDescriptor(16, 8, 8, TargetBuffer.Color) },
|
{ GalImageFormat.Astc2D6x6, new ImageDescriptor(16, 6, 6, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.Astc2D10x10, new ImageDescriptor(16, 10, 10, TargetBuffer.Color) },
|
{ GalImageFormat.Astc2D8x8, new ImageDescriptor(16, 8, 8, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.Astc2D12x12, new ImageDescriptor(16, 12, 12, TargetBuffer.Color) },
|
{ GalImageFormat.Astc2D10x10, new ImageDescriptor(16, 10, 10, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.Astc2D5x4, new ImageDescriptor(16, 5, 4, TargetBuffer.Color) },
|
{ GalImageFormat.Astc2D12x12, new ImageDescriptor(16, 12, 12, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.Astc2D6x5, new ImageDescriptor(16, 6, 5, TargetBuffer.Color) },
|
{ GalImageFormat.Astc2D5x4, new ImageDescriptor(16, 5, 4, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.Astc2D8x6, new ImageDescriptor(16, 8, 6, TargetBuffer.Color) },
|
{ GalImageFormat.Astc2D6x5, new ImageDescriptor(16, 6, 5, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.Astc2D10x8, new ImageDescriptor(16, 10, 8, TargetBuffer.Color) },
|
{ GalImageFormat.Astc2D8x6, new ImageDescriptor(16, 8, 6, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.Astc2D12x10, new ImageDescriptor(16, 12, 10, TargetBuffer.Color) },
|
{ GalImageFormat.Astc2D10x8, new ImageDescriptor(16, 10, 8, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.Astc2D8x5, new ImageDescriptor(16, 8, 5, TargetBuffer.Color) },
|
{ GalImageFormat.Astc2D12x10, new ImageDescriptor(16, 12, 10, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.Astc2D10x5, new ImageDescriptor(16, 10, 5, TargetBuffer.Color) },
|
{ GalImageFormat.Astc2D8x5, new ImageDescriptor(16, 8, 5, 1, TargetBuffer.Color) },
|
||||||
{ GalImageFormat.Astc2D10x6, new ImageDescriptor(16, 10, 6, TargetBuffer.Color) },
|
{ GalImageFormat.Astc2D10x5, new ImageDescriptor(16, 10, 5, 1, TargetBuffer.Color) },
|
||||||
|
{ GalImageFormat.Astc2D10x6, new ImageDescriptor(16, 10, 6, 1, TargetBuffer.Color) },
|
||||||
|
|
||||||
{ GalImageFormat.D16, new ImageDescriptor(2, 1, 1, TargetBuffer.Depth) },
|
{ GalImageFormat.D16, new ImageDescriptor(2, 1, 1, 1, TargetBuffer.Depth) },
|
||||||
{ GalImageFormat.D24, new ImageDescriptor(4, 1, 1, TargetBuffer.Depth) },
|
{ GalImageFormat.D24, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Depth) },
|
||||||
{ GalImageFormat.D24S8, new ImageDescriptor(4, 1, 1, TargetBuffer.DepthStencil) },
|
{ GalImageFormat.D24S8, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.DepthStencil) },
|
||||||
{ GalImageFormat.D32, new ImageDescriptor(4, 1, 1, TargetBuffer.Depth) },
|
{ GalImageFormat.D32, new ImageDescriptor(4, 1, 1, 1, TargetBuffer.Depth) },
|
||||||
{ GalImageFormat.D32S8, new ImageDescriptor(8, 1, 1, TargetBuffer.DepthStencil) }
|
{ GalImageFormat.D32S8, new ImageDescriptor(8, 1, 1, 1, TargetBuffer.DepthStencil) }
|
||||||
};
|
};
|
||||||
|
|
||||||
public static GalImageFormat ConvertTexture(
|
public static GalImageFormat ConvertTexture(
|
||||||
|
@ -225,6 +229,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
throw new NotImplementedException(Format.ToString());
|
throw new NotImplementedException(Format.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: non 2d
|
||||||
public static byte[] ReadTexture(IMemory Memory, GalImage Image, long Position)
|
public static byte[] ReadTexture(IMemory Memory, GalImage Image, long Position)
|
||||||
{
|
{
|
||||||
MemoryManager CpuMemory;
|
MemoryManager CpuMemory;
|
||||||
|
@ -238,52 +243,61 @@ namespace Ryujinx.Graphics.Texture
|
||||||
CpuMemory = (MemoryManager)Memory;
|
CpuMemory = (MemoryManager)Memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Debug.Assert(Image.TextureType == TextureType.TwoD, "non 2d texture read");
|
||||||
|
|
||||||
ISwizzle Swizzle = TextureHelper.GetSwizzle(Image);
|
ISwizzle Swizzle = TextureHelper.GetSwizzle(Image);
|
||||||
|
|
||||||
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
||||||
|
|
||||||
(int Width, int Height) = GetImageSizeInBlocks(Image);
|
(int Width, int Height, int Depth) = GetImageSizeInBlocks(Image);
|
||||||
|
|
||||||
int BytesPerPixel = Desc.BytesPerPixel;
|
int BytesPerPixel = Desc.BytesPerPixel;
|
||||||
|
|
||||||
//Note: Each row of the texture needs to be aligned to 4 bytes.
|
//Note: Each row of the texture needs to be aligned to 4 bytes.
|
||||||
int Pitch = (Width * BytesPerPixel + 3) & ~3;
|
int Pitch = (Width * BytesPerPixel + 3) & ~3;
|
||||||
|
|
||||||
byte[] Data = new byte[Height * Pitch];
|
byte[] Data = new byte[Height * Pitch * Depth];
|
||||||
|
for (int Z = 0; Z < Depth; Z++)
|
||||||
for (int Y = 0; Y < Height; Y++)
|
|
||||||
{
|
{
|
||||||
int OutOffs = Y * Pitch;
|
for (int Y = 0; Y < Height; Y++)
|
||||||
|
|
||||||
for (int X = 0; X < Width; X++)
|
|
||||||
{
|
{
|
||||||
long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y);
|
int OutOffs = Y * Pitch + (Z * Width * Height * BytesPerPixel);
|
||||||
|
|
||||||
CpuMemory.ReadBytes(Position + Offset, Data, OutOffs, BytesPerPixel);
|
for (int X = 0; X < Width; X++)
|
||||||
|
{
|
||||||
|
long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y, Z);
|
||||||
|
|
||||||
OutOffs += BytesPerPixel;
|
CpuMemory.ReadBytes(Position + Offset, Data, OutOffs, BytesPerPixel);
|
||||||
|
|
||||||
|
OutOffs += BytesPerPixel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return Data;
|
return Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: non 2d
|
||||||
public static void WriteTexture(NvGpuVmm Vmm, GalImage Image, long Position, byte[] Data)
|
public static void WriteTexture(NvGpuVmm Vmm, GalImage Image, long Position, byte[] Data)
|
||||||
{
|
{
|
||||||
ISwizzle Swizzle = TextureHelper.GetSwizzle(Image);
|
ISwizzle Swizzle = TextureHelper.GetSwizzle(Image);
|
||||||
|
|
||||||
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
||||||
|
|
||||||
(int Width, int Height) = ImageUtils.GetImageSizeInBlocks(Image);
|
(int Width, int Height, int Depth) = ImageUtils.GetImageSizeInBlocks(Image);
|
||||||
|
|
||||||
int BytesPerPixel = Desc.BytesPerPixel;
|
int BytesPerPixel = Desc.BytesPerPixel;
|
||||||
|
|
||||||
int InOffs = 0;
|
int InOffs = 0;
|
||||||
|
|
||||||
|
Debug.Assert(Image.TextureType == TextureType.TwoD, "non 2d texture write");
|
||||||
|
|
||||||
|
for (int Z = 0; Z < Depth; Z++)
|
||||||
for (int Y = 0; Y < Height; Y++)
|
for (int Y = 0; Y < Height; Y++)
|
||||||
for (int X = 0; X < Width; X++)
|
for (int X = 0; X < Width; X++)
|
||||||
{
|
{
|
||||||
long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y);
|
long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y, Z);
|
||||||
|
|
||||||
Vmm.Memory.WriteBytes(Position + Offset, Data, InOffs, BytesPerPixel);
|
Vmm.Memory.WriteBytes(Position + Offset, Data, InOffs, BytesPerPixel);
|
||||||
|
|
||||||
|
@ -291,6 +305,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: SUPPORT NON 2D
|
||||||
public static bool CopyTexture(
|
public static bool CopyTexture(
|
||||||
NvGpuVmm Vmm,
|
NvGpuVmm Vmm,
|
||||||
GalImage SrcImage,
|
GalImage SrcImage,
|
||||||
|
@ -319,8 +334,8 @@ namespace Ryujinx.Graphics.Texture
|
||||||
for (int Y = 0; Y < Height; Y++)
|
for (int Y = 0; Y < Height; Y++)
|
||||||
for (int X = 0; X < Width; X++)
|
for (int X = 0; X < Width; X++)
|
||||||
{
|
{
|
||||||
long SrcOffset = (uint)SrcSwizzle.GetSwizzleOffset(SrcX + X, SrcY + Y);
|
long SrcOffset = (uint)SrcSwizzle.GetSwizzleOffset(SrcX + X, SrcY + Y, 0);
|
||||||
long DstOffset = (uint)DstSwizzle.GetSwizzleOffset(DstX + X, DstY + Y);
|
long DstOffset = (uint)DstSwizzle.GetSwizzleOffset(DstX + X, DstY + Y, 0);
|
||||||
|
|
||||||
byte[] Texel = Vmm.ReadBytes(SrcAddress + SrcOffset, BytesPerPixel);
|
byte[] Texel = Vmm.ReadBytes(SrcAddress + SrcOffset, BytesPerPixel);
|
||||||
|
|
||||||
|
@ -330,15 +345,31 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Check if that does the trick
|
||||||
public static int GetSize(GalImage Image)
|
public static int GetSize(GalImage Image)
|
||||||
{
|
{
|
||||||
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
||||||
|
|
||||||
|
int ComponentCount = GetCoordsCountTextureType(Image.TextureType);
|
||||||
|
|
||||||
|
if (IsArray(Image.TextureType))
|
||||||
|
ComponentCount--;
|
||||||
|
|
||||||
int Width = DivRoundUp(Image.Width, Desc.BlockWidth);
|
int Width = DivRoundUp(Image.Width, Desc.BlockWidth);
|
||||||
int Height = DivRoundUp(Image.Height, Desc.BlockHeight);
|
int Height = DivRoundUp(Image.Height, Desc.BlockHeight);
|
||||||
|
int Depth = DivRoundUp(Image.Depth, Desc.BlockDepth);
|
||||||
|
|
||||||
// TODO: multi format
|
switch (ComponentCount)
|
||||||
return Desc.BytesPerPixel * Width * Height;
|
{
|
||||||
|
case 1:
|
||||||
|
return Desc.BytesPerPixel * Width;
|
||||||
|
case 2:
|
||||||
|
return Desc.BytesPerPixel * Width * Height;
|
||||||
|
case 3:
|
||||||
|
return Desc.BytesPerPixel * Width * Height * Depth;
|
||||||
|
default:
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int GetPitch(GalImageFormat Format, int Width)
|
public static int GetPitch(GalImageFormat Format, int Width)
|
||||||
|
@ -362,6 +393,11 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return GetImageDescriptor(Format).BlockHeight;
|
return GetImageDescriptor(Format).BlockHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int GetBlockDepth(GalImageFormat Format)
|
||||||
|
{
|
||||||
|
return GetImageDescriptor(Format).BlockDepth;
|
||||||
|
}
|
||||||
|
|
||||||
public static int GetAlignedWidth(GalImage Image)
|
public static int GetAlignedWidth(GalImage Image)
|
||||||
{
|
{
|
||||||
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
||||||
|
@ -380,12 +416,14 @@ namespace Ryujinx.Graphics.Texture
|
||||||
return (Image.Width + AlignMask) & ~AlignMask;
|
return (Image.Width + AlignMask) & ~AlignMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (int Width, int Height) GetImageSizeInBlocks(GalImage Image)
|
// TODO: non 2d
|
||||||
|
public static (int Width, int Height, int Depth) GetImageSizeInBlocks(GalImage Image)
|
||||||
{
|
{
|
||||||
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
||||||
|
|
||||||
return (DivRoundUp(Image.Width, Desc.BlockWidth),
|
return (DivRoundUp(Image.Width, Desc.BlockWidth),
|
||||||
DivRoundUp(Image.Height, Desc.BlockHeight));
|
DivRoundUp(Image.Height, Desc.BlockHeight),
|
||||||
|
DivRoundUp(Image.Depth, Desc.BlockDepth));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int GetBytesPerPixel(GalImageFormat Format)
|
public static int GetBytesPerPixel(GalImageFormat Format)
|
||||||
|
|
|
@ -5,15 +5,18 @@ namespace Ryujinx.Graphics.Texture
|
||||||
private int Pitch;
|
private int Pitch;
|
||||||
private int Bpp;
|
private int Bpp;
|
||||||
|
|
||||||
public LinearSwizzle(int Pitch, int Bpp)
|
private int ZLayer;
|
||||||
|
|
||||||
|
public LinearSwizzle(int Pitch, int Bpp, int Width, int Height)
|
||||||
{
|
{
|
||||||
this.Pitch = Pitch;
|
this.Pitch = Pitch;
|
||||||
this.Bpp = Bpp;
|
this.Bpp = Bpp;
|
||||||
|
this.ZLayer = Width * Height * Bpp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetSwizzleOffset(int X, int Y)
|
public int GetSwizzleOffset(int X, int Y, int Z)
|
||||||
{
|
{
|
||||||
return X * Bpp + Y * Pitch;
|
return Z * ZLayer + X * Bpp + Y * Pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,6 +2,7 @@ using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.Gal;
|
using Ryujinx.Graphics.Gal;
|
||||||
using Ryujinx.Graphics.Memory;
|
using Ryujinx.Graphics.Memory;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Texture
|
namespace Ryujinx.Graphics.Texture
|
||||||
{
|
{
|
||||||
|
@ -22,6 +23,8 @@ namespace Ryujinx.Graphics.Texture
|
||||||
|
|
||||||
TextureSwizzle Swizzle = (TextureSwizzle)((Tic[2] >> 21) & 7);
|
TextureSwizzle Swizzle = (TextureSwizzle)((Tic[2] >> 21) & 7);
|
||||||
|
|
||||||
|
int MaxMipmapLevel = (Tic[3] >> 28) & 0xF + 1;
|
||||||
|
|
||||||
GalMemoryLayout Layout;
|
GalMemoryLayout Layout;
|
||||||
|
|
||||||
if (Swizzle == TextureSwizzle.BlockLinear ||
|
if (Swizzle == TextureSwizzle.BlockLinear ||
|
||||||
|
@ -44,6 +47,11 @@ namespace Ryujinx.Graphics.Texture
|
||||||
int Height = (Tic[5] & 0xffff) + 1;
|
int Height = (Tic[5] & 0xffff) + 1;
|
||||||
int Depth = ((Tic[5] >> 16) & 0x3fff) + 1;
|
int Depth = ((Tic[5] >> 16) & 0x3fff) + 1;
|
||||||
|
|
||||||
|
if (TextureType == TextureType.OneD)
|
||||||
|
{
|
||||||
|
Height = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (TextureType == TextureType.TwoD || TextureType == TextureType.OneD)
|
if (TextureType == TextureType.TwoD || TextureType == TextureType.OneD)
|
||||||
{
|
{
|
||||||
Depth = 1;
|
Depth = 1;
|
||||||
|
@ -58,6 +66,7 @@ namespace Ryujinx.Graphics.Texture
|
||||||
Layout,
|
Layout,
|
||||||
Format,
|
Format,
|
||||||
TextureType,
|
TextureType,
|
||||||
|
MaxMipmapLevel,
|
||||||
XSource,
|
XSource,
|
||||||
YSource,
|
YSource,
|
||||||
ZSource,
|
ZSource,
|
||||||
|
|
|
@ -9,9 +9,11 @@ namespace Ryujinx.Graphics.Texture
|
||||||
public static ISwizzle GetSwizzle(GalImage Image)
|
public static ISwizzle GetSwizzle(GalImage Image)
|
||||||
{
|
{
|
||||||
int BlockWidth = ImageUtils.GetBlockWidth (Image.Format);
|
int BlockWidth = ImageUtils.GetBlockWidth (Image.Format);
|
||||||
|
int BlockHeight = ImageUtils.GetBlockHeight (Image.Format);
|
||||||
int BytesPerPixel = ImageUtils.GetBytesPerPixel(Image.Format);
|
int BytesPerPixel = ImageUtils.GetBytesPerPixel(Image.Format);
|
||||||
|
|
||||||
int Width = (Image.Width + (BlockWidth - 1)) / BlockWidth;
|
int Width = (Image.Width + (BlockWidth - 1)) / BlockWidth;
|
||||||
|
int Height = (Image.Height + (BlockHeight - 1)) / BlockHeight;
|
||||||
|
|
||||||
if (Image.Layout == GalMemoryLayout.BlockLinear)
|
if (Image.Layout == GalMemoryLayout.BlockLinear)
|
||||||
{
|
{
|
||||||
|
@ -19,11 +21,11 @@ namespace Ryujinx.Graphics.Texture
|
||||||
|
|
||||||
Width = (Width + AlignMask) & ~AlignMask;
|
Width = (Width + AlignMask) & ~AlignMask;
|
||||||
|
|
||||||
return new BlockLinearSwizzle(Width, BytesPerPixel, Image.GobBlockHeight);
|
return new BlockLinearSwizzle(Width, Height, BytesPerPixel, Image.GobBlockHeight);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new LinearSwizzle(Image.Pitch, BytesPerPixel);
|
return new LinearSwizzle(Image.Pitch, BytesPerPixel, Width, Height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue