| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 |
- 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);
- }
- }
- }
|