aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Gpu/Image/TextureInfo.cs
diff options
context:
space:
mode:
authorTSR Berry <20988865+TSRBerry@users.noreply.github.com>2023-04-08 01:22:00 +0200
committerMary <thog@protonmail.com>2023-04-27 23:51:14 +0200
commitcee712105850ac3385cd0091a923438167433f9f (patch)
tree4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /src/Ryujinx.Graphics.Gpu/Image/TextureInfo.cs
parentcd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff)
Move solution and projects to src
Diffstat (limited to 'src/Ryujinx.Graphics.Gpu/Image/TextureInfo.cs')
-rw-r--r--src/Ryujinx.Graphics.Gpu/Image/TextureInfo.cs381
1 files changed, 381 insertions, 0 deletions
diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureInfo.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureInfo.cs
new file mode 100644
index 00000000..a7ee12bc
--- /dev/null
+++ b/src/Ryujinx.Graphics.Gpu/Image/TextureInfo.cs
@@ -0,0 +1,381 @@
+using Ryujinx.Common;
+using Ryujinx.Graphics.GAL;
+using Ryujinx.Graphics.Texture;
+using System;
+
+namespace Ryujinx.Graphics.Gpu.Image
+{
+ /// <summary>
+ /// Texture information.
+ /// </summary>
+ readonly struct TextureInfo
+ {
+ /// <summary>
+ /// Address of the texture in GPU mapped memory.
+ /// </summary>
+ public ulong GpuAddress { get; }
+
+ /// <summary>
+ /// The width of the texture.
+ /// </summary>
+ public int Width { get; }
+
+ /// <summary>
+ /// The height of the texture, or layers count for 1D array textures.
+ /// </summary>
+ public int Height { get; }
+
+ /// <summary>
+ /// The depth of the texture (for 3D textures), or layers count for array textures.
+ /// </summary>
+ public int DepthOrLayers { get; }
+
+ /// <summary>
+ /// The number of mipmap levels of the texture.
+ /// </summary>
+ public int Levels { get; }
+
+ /// <summary>
+ /// The number of samples in the X direction for multisampled textures.
+ /// </summary>
+ public int SamplesInX { get; }
+
+ /// <summary>
+ /// The number of samples in the Y direction for multisampled textures.
+ /// </summary>
+ public int SamplesInY { get; }
+
+ /// <summary>
+ /// The number of bytes per line for linear textures.
+ /// </summary>
+ public int Stride { get; }
+
+ /// <summary>
+ /// Indicates whenever or not the texture is a linear texture.
+ /// </summary>
+ public bool IsLinear { get; }
+
+ /// <summary>
+ /// GOB blocks in the Y direction, for block linear textures.
+ /// </summary>
+ public int GobBlocksInY { get; }
+
+ /// <summary>
+ /// GOB blocks in the Z direction, for block linear textures.
+ /// </summary>
+ public int GobBlocksInZ { get; }
+
+ /// <summary>
+ /// Number of GOB blocks per tile in the X direction, for block linear textures.
+ /// </summary>
+ public int GobBlocksInTileX { get; }
+
+ /// <summary>
+ /// Total number of samples for multisampled textures.
+ /// </summary>
+ public int Samples => SamplesInX * SamplesInY;
+
+ /// <summary>
+ /// Texture target type.
+ /// </summary>
+ public Target Target { get; }
+
+ /// <summary>
+ /// Texture format information.
+ /// </summary>
+ public FormatInfo FormatInfo { get; }
+
+ /// <summary>
+ /// Depth-stencil mode of the texture. This defines whenever the depth or stencil value is read from shaders,
+ /// for depth-stencil texture formats.
+ /// </summary>
+ public DepthStencilMode DepthStencilMode { get; }
+
+ /// <summary>
+ /// Texture swizzle for the red color channel.
+ /// </summary>
+ public SwizzleComponent SwizzleR { get; }
+
+ /// <summary>
+ /// Texture swizzle for the green color channel.
+ /// </summary>
+ public SwizzleComponent SwizzleG { get; }
+
+ /// <summary>
+ /// Texture swizzle for the blue color channel.
+ /// </summary>
+ public SwizzleComponent SwizzleB { get; }
+
+ /// <summary>
+ /// Texture swizzle for the alpha color channel.
+ /// </summary>
+ public SwizzleComponent SwizzleA { get; }
+
+ /// <summary>
+ /// Constructs the texture information structure.
+ /// </summary>
+ /// <param name="gpuAddress">The GPU address of the texture</param>
+ /// <param name="width">The width of the texture</param>
+ /// <param name="height">The height or the texture</param>
+ /// <param name="depthOrLayers">The depth or layers count of the texture</param>
+ /// <param name="levels">The amount of mipmap levels of the texture</param>
+ /// <param name="samplesInX">The number of samples in the X direction for multisample textures, should be 1 otherwise</param>
+ /// <param name="samplesInY">The number of samples in the Y direction for multisample textures, should be 1 otherwise</param>
+ /// <param name="stride">The stride for linear textures</param>
+ /// <param name="isLinear">Whenever the texture is linear or block linear</param>
+ /// <param name="gobBlocksInY">Number of GOB blocks in the Y direction</param>
+ /// <param name="gobBlocksInZ">Number of GOB blocks in the Z direction</param>
+ /// <param name="gobBlocksInTileX">Number of GOB blocks per tile in the X direction</param>
+ /// <param name="target">Texture target type</param>
+ /// <param name="formatInfo">Texture format information</param>
+ /// <param name="depthStencilMode">Depth-stencil mode</param>
+ /// <param name="swizzleR">Swizzle for the red color channel</param>
+ /// <param name="swizzleG">Swizzle for the green color channel</param>
+ /// <param name="swizzleB">Swizzle for the blue color channel</param>
+ /// <param name="swizzleA">Swizzle for the alpha color channel</param>
+ public TextureInfo(
+ ulong gpuAddress,
+ int width,
+ int height,
+ int depthOrLayers,
+ int levels,
+ int samplesInX,
+ int samplesInY,
+ int stride,
+ bool isLinear,
+ int gobBlocksInY,
+ int gobBlocksInZ,
+ int gobBlocksInTileX,
+ Target target,
+ FormatInfo formatInfo,
+ DepthStencilMode depthStencilMode = DepthStencilMode.Depth,
+ SwizzleComponent swizzleR = SwizzleComponent.Red,
+ SwizzleComponent swizzleG = SwizzleComponent.Green,
+ SwizzleComponent swizzleB = SwizzleComponent.Blue,
+ SwizzleComponent swizzleA = SwizzleComponent.Alpha)
+ {
+ GpuAddress = gpuAddress;
+ Width = width;
+ Height = height;
+ DepthOrLayers = depthOrLayers;
+ Levels = levels;
+ SamplesInX = samplesInX;
+ SamplesInY = samplesInY;
+ Stride = stride;
+ IsLinear = isLinear;
+ GobBlocksInY = gobBlocksInY;
+ GobBlocksInZ = gobBlocksInZ;
+ GobBlocksInTileX = gobBlocksInTileX;
+ Target = target;
+ FormatInfo = formatInfo;
+ DepthStencilMode = depthStencilMode;
+ SwizzleR = swizzleR;
+ SwizzleG = swizzleG;
+ SwizzleB = swizzleB;
+ SwizzleA = swizzleA;
+ }
+
+ /// <summary>
+ /// Gets the real texture depth.
+ /// Returns 1 for any target other than 3D textures.
+ /// </summary>
+ /// <returns>Texture depth</returns>
+ public int GetDepth()
+ {
+ return GetDepth(Target, DepthOrLayers);
+ }
+
+ /// <summary>
+ /// Gets the real texture depth.
+ /// Returns 1 for any target other than 3D textures.
+ /// </summary>
+ /// <param name="target">Texture target</param>
+ /// <param name="depthOrLayers">Texture depth if the texture is 3D, otherwise ignored</param>
+ /// <returns>Texture depth</returns>
+ public static int GetDepth(Target target, int depthOrLayers)
+ {
+ return target == Target.Texture3D ? depthOrLayers : 1;
+ }
+
+ /// <summary>
+ /// Gets the number of layers of the texture.
+ /// Returns 1 for non-array textures, 6 for cubemap textures, and layer faces for cubemap array textures.
+ /// </summary>
+ /// <returns>The number of texture layers</returns>
+ public int GetLayers()
+ {
+ return GetLayers(Target, DepthOrLayers);
+ }
+
+ /// <summary>
+ /// Gets the number of layers of the texture.
+ /// Returns 1 for non-array textures, 6 for cubemap textures, and layer faces for cubemap array textures.
+ /// </summary>
+ /// <param name="target">Texture target</param>
+ /// <param name="depthOrLayers">Texture layers if the is a array texture, ignored otherwise</param>
+ /// <returns>The number of texture layers</returns>
+ public static int GetLayers(Target target, int depthOrLayers)
+ {
+ if (target == Target.Texture2DArray || target == Target.Texture2DMultisampleArray)
+ {
+ return depthOrLayers;
+ }
+ else if (target == Target.CubemapArray)
+ {
+ return depthOrLayers * 6;
+ }
+ else if (target == Target.Cubemap)
+ {
+ return 6;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+
+ /// <summary>
+ /// Gets the number of 2D slices of the texture.
+ /// Returns 6 for cubemap textures, layer faces for cubemap array textures, and DepthOrLayers for everything else.
+ /// </summary>
+ /// <returns>The number of texture slices</returns>
+ public int GetSlices()
+ {
+ if (Target == Target.Texture3D || Target == Target.Texture2DArray || Target == Target.Texture2DMultisampleArray)
+ {
+ return DepthOrLayers;
+ }
+ else if (Target == Target.CubemapArray)
+ {
+ return DepthOrLayers * 6;
+ }
+ else if (Target == Target.Cubemap)
+ {
+ return 6;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+
+ /// <summary>
+ /// Calculates the size information from the texture information.
+ /// </summary>
+ /// <param name="layerSize">Optional size of each texture layer in bytes</param>
+ /// <returns>Texture size information</returns>
+ public SizeInfo CalculateSizeInfo(int layerSize = 0)
+ {
+ if (Target == Target.TextureBuffer)
+ {
+ return new SizeInfo(Width * FormatInfo.BytesPerPixel);
+ }
+ else if (IsLinear)
+ {
+ return SizeCalculator.GetLinearTextureSize(
+ Stride,
+ Height,
+ FormatInfo.BlockHeight);
+ }
+ else
+ {
+ return SizeCalculator.GetBlockLinearTextureSize(
+ Width,
+ Height,
+ GetDepth(),
+ Levels,
+ GetLayers(),
+ FormatInfo.BlockWidth,
+ FormatInfo.BlockHeight,
+ FormatInfo.BytesPerPixel,
+ GobBlocksInY,
+ GobBlocksInZ,
+ GobBlocksInTileX,
+ layerSize);
+ }
+ }
+
+ /// <summary>
+ /// Creates texture information for a given mipmap level of the specified parent texture and this information.
+ /// </summary>
+ /// <param name="parent">The parent texture</param>
+ /// <param name="firstLevel">The first level of the texture view</param>
+ /// <returns>The adjusted texture information with the new size</returns>
+ public TextureInfo CreateInfoForLevelView(Texture parent, int firstLevel)
+ {
+ // When the texture is used as view of another texture, we must
+ // ensure that the sizes are valid, otherwise data uploads would fail
+ // (and the size wouldn't match the real size used on the host API).
+ // Given a parent texture from where the view is created, we have the
+ // following rules:
+ // - The view size must be equal to the parent size, divided by (2 ^ l),
+ // where l is the first mipmap level of the view. The division result must
+ // be rounded down, and the result must be clamped to 1.
+ // - If the parent format is compressed, and the view format isn't, the
+ // view size is calculated as above, but the width and height of the
+ // view must be also divided by the compressed format block width and height.
+ // - If the parent format is not compressed, and the view is, the view
+ // size is calculated as described on the first point, but the width and height
+ // of the view must be also multiplied by the block width and height.
+ int width = Math.Max(1, parent.Info.Width >> firstLevel);
+ int height = Math.Max(1, parent.Info.Height >> firstLevel);
+
+ if (parent.Info.FormatInfo.IsCompressed && !FormatInfo.IsCompressed)
+ {
+ width = BitUtils.DivRoundUp(width, parent.Info.FormatInfo.BlockWidth);
+ height = BitUtils.DivRoundUp(height, parent.Info.FormatInfo.BlockHeight);
+ }
+ else if (!parent.Info.FormatInfo.IsCompressed && FormatInfo.IsCompressed)
+ {
+ width *= FormatInfo.BlockWidth;
+ height *= FormatInfo.BlockHeight;
+ }
+
+ int depthOrLayers;
+
+ if (Target == Target.Texture3D)
+ {
+ depthOrLayers = Math.Max(1, parent.Info.DepthOrLayers >> firstLevel);
+ }
+ else
+ {
+ depthOrLayers = DepthOrLayers;
+ }
+
+ // 2D and 2D multisample textures are not considered compatible.
+ // This specific case is required for copies, where the source texture might be multisample.
+ // In this case, we inherit the parent texture multisample state.
+ Target target = Target;
+ int samplesInX = SamplesInX;
+ int samplesInY = SamplesInY;
+
+ if (target == Target.Texture2D && parent.Target == Target.Texture2DMultisample)
+ {
+ target = Target.Texture2DMultisample;
+ samplesInX = parent.Info.SamplesInX;
+ samplesInY = parent.Info.SamplesInY;
+ }
+
+ return new TextureInfo(
+ GpuAddress,
+ width,
+ height,
+ depthOrLayers,
+ Levels,
+ samplesInX,
+ samplesInY,
+ Stride,
+ IsLinear,
+ GobBlocksInY,
+ GobBlocksInZ,
+ GobBlocksInTileX,
+ target,
+ FormatInfo,
+ DepthStencilMode,
+ SwizzleR,
+ SwizzleG,
+ SwizzleB,
+ SwizzleA);
+ }
+ }
+} \ No newline at end of file