Пример #1
0
 /// <summary>
 /// Returns the total number of samples from the MSAA mode.
 /// </summary>
 /// <param name="msaaMode">The MSAA mode</param>
 /// <returns>The total number of samples</returns>
 public static int SamplesCount(this TextureMsaaMode msaaMode)
 {
     return(msaaMode switch
     {
         TextureMsaaMode.Ms2x1 => 2,
         TextureMsaaMode.Ms2x2 => 4,
         TextureMsaaMode.Ms4x2 => 8,
         TextureMsaaMode.Ms4x4 => 16,
         _ => 1
     });
Пример #2
0
        /// <summary>
        /// Gets texture information from a texture descriptor.
        /// </summary>
        /// <param name="descriptor">The texture descriptor</param>
        /// <param name="layerSize">Layer size for textures using a sub-range of mipmap levels, otherwise 0</param>
        /// <returns>The texture information</returns>
        private TextureInfo GetInfo(TextureDescriptor descriptor, out int layerSize)
        {
            int width         = descriptor.UnpackWidth();
            int height        = descriptor.UnpackHeight();
            int depthOrLayers = descriptor.UnpackDepth();
            int levels        = descriptor.UnpackLevels();

            TextureMsaaMode msaaMode = descriptor.UnpackTextureMsaaMode();

            int samplesInX = msaaMode.SamplesInX();
            int samplesInY = msaaMode.SamplesInY();

            int stride = descriptor.UnpackStride();

            TextureDescriptorType descriptorType = descriptor.UnpackTextureDescriptorType();

            bool isLinear = descriptorType == TextureDescriptorType.Linear;

            Target target = descriptor.UnpackTextureTarget().Convert((samplesInX | samplesInY) != 1);

            // We use 2D targets for 1D textures as that makes texture cache
            // management easier. We don't know the target for render target
            // and copies, so those would normally use 2D targets, which are
            // not compatible with 1D targets. By doing that we also allow those
            // to match when looking for compatible textures on the cache.
            if (target == Target.Texture1D)
            {
                target = Target.Texture2D;
                height = 1;
            }
            else if (target == Target.Texture1DArray)
            {
                target = Target.Texture2DArray;
                height = 1;
            }

            uint format = descriptor.UnpackFormat();
            bool srgb   = descriptor.UnpackSrgb();

            ulong gpuVa = descriptor.UnpackAddress();

            if (!FormatTable.TryGetTextureFormat(format, srgb, out FormatInfo formatInfo))
            {
                if (Context.MemoryManager.IsMapped(gpuVa) && (int)format > 0)
                {
                    Logger.Error?.Print(LogClass.Gpu, $"Invalid texture format 0x{format:X} (sRGB: {srgb}).");
                }

                formatInfo = FormatInfo.Default;
            }

            int gobBlocksInY = descriptor.UnpackGobBlocksInY();
            int gobBlocksInZ = descriptor.UnpackGobBlocksInZ();

            int gobBlocksInTileX = descriptor.UnpackGobBlocksInTileX();

            layerSize = 0;

            int minLod = descriptor.UnpackBaseLevel();
            int maxLod = descriptor.UnpackMaxLevelInclusive();

            // Linear textures don't support mipmaps, so we don't handle this case here.
            if ((minLod != 0 || maxLod + 1 != levels) && target != Target.TextureBuffer && !isLinear)
            {
                int depth  = TextureInfo.GetDepth(target, depthOrLayers);
                int layers = TextureInfo.GetLayers(target, depthOrLayers);

                SizeInfo sizeInfo = SizeCalculator.GetBlockLinearTextureSize(
                    width,
                    height,
                    depth,
                    levels,
                    layers,
                    formatInfo.BlockWidth,
                    formatInfo.BlockHeight,
                    formatInfo.BytesPerPixel,
                    gobBlocksInY,
                    gobBlocksInZ,
                    gobBlocksInTileX);

                layerSize = sizeInfo.LayerSize;

                if (minLod != 0 && minLod < levels)
                {
                    // If the base level is not zero, we additionally add the mip level offset
                    // to the address, this allows the texture manager to find the base level from the
                    // address if there is a overlapping texture on the cache that can contain the new texture.
                    gpuVa += (ulong)sizeInfo.GetMipOffset(minLod);

                    width  = Math.Max(1, width >> minLod);
                    height = Math.Max(1, height >> minLod);

                    if (target == Target.Texture3D)
                    {
                        depthOrLayers = Math.Max(1, depthOrLayers >> minLod);
                    }

                    (gobBlocksInY, gobBlocksInZ) = SizeCalculator.GetMipGobBlockSizes(height, depth, formatInfo.BlockHeight, gobBlocksInY, gobBlocksInZ);
                }

                levels = (maxLod - minLod) + 1;
            }

            SwizzleComponent swizzleR = descriptor.UnpackSwizzleR().Convert();
            SwizzleComponent swizzleG = descriptor.UnpackSwizzleG().Convert();
            SwizzleComponent swizzleB = descriptor.UnpackSwizzleB().Convert();
            SwizzleComponent swizzleA = descriptor.UnpackSwizzleA().Convert();

            DepthStencilMode depthStencilMode = GetDepthStencilMode(
                formatInfo.Format,
                swizzleR,
                swizzleG,
                swizzleB,
                swizzleA);

            if (formatInfo.Format.IsDepthOrStencil())
            {
                swizzleR = SwizzleComponent.Red;
                swizzleG = SwizzleComponent.Red;
                swizzleB = SwizzleComponent.Red;

                if (depthStencilMode == DepthStencilMode.Depth)
                {
                    swizzleA = SwizzleComponent.One;
                }
                else
                {
                    swizzleA = SwizzleComponent.Red;
                }
            }

            return(new TextureInfo(
                       gpuVa,
                       width,
                       height,
                       depthOrLayers,
                       levels,
                       samplesInX,
                       samplesInY,
                       stride,
                       isLinear,
                       gobBlocksInY,
                       gobBlocksInZ,
                       gobBlocksInTileX,
                       target,
                       formatInfo,
                       depthStencilMode,
                       swizzleR,
                       swizzleG,
                       swizzleB,
                       swizzleA));
        }
Пример #3
0
        /// <summary>
        /// Gets texture information from a texture descriptor.
        /// </summary>
        /// <param name="descriptor">The texture descriptor</param>
        /// <returns>The texture information</returns>
        private TextureInfo GetInfo(TextureDescriptor descriptor)
        {
            ulong address = Context.MemoryManager.Translate(descriptor.UnpackAddress());

            int width         = descriptor.UnpackWidth();
            int height        = descriptor.UnpackHeight();
            int depthOrLayers = descriptor.UnpackDepth();
            int levels        = descriptor.UnpackLevels();

            TextureMsaaMode msaaMode = descriptor.UnpackTextureMsaaMode();

            int samplesInX = msaaMode.SamplesInX();
            int samplesInY = msaaMode.SamplesInY();

            int stride = descriptor.UnpackStride();

            TextureDescriptorType descriptorType = descriptor.UnpackTextureDescriptorType();

            bool isLinear = descriptorType == TextureDescriptorType.Linear;

            Target target = descriptor.UnpackTextureTarget().Convert((samplesInX | samplesInY) != 1);

            uint format = descriptor.UnpackFormat();
            bool srgb   = descriptor.UnpackSrgb();

            if (!FormatTable.TryGetTextureFormat(format, srgb, out FormatInfo formatInfo))
            {
                if ((long)address > 0L && (int)format > 0)
                {
                    Logger.PrintError(LogClass.Gpu, $"Invalid texture format 0x{format:X} (sRGB: {srgb}).");
                }

                formatInfo = FormatInfo.Default;
            }

            int gobBlocksInY = descriptor.UnpackGobBlocksInY();
            int gobBlocksInZ = descriptor.UnpackGobBlocksInZ();

            int gobBlocksInTileX = descriptor.UnpackGobBlocksInTileX();

            SwizzleComponent swizzleR = descriptor.UnpackSwizzleR().Convert();
            SwizzleComponent swizzleG = descriptor.UnpackSwizzleG().Convert();
            SwizzleComponent swizzleB = descriptor.UnpackSwizzleB().Convert();
            SwizzleComponent swizzleA = descriptor.UnpackSwizzleA().Convert();

            DepthStencilMode depthStencilMode = GetDepthStencilMode(
                formatInfo.Format,
                swizzleR,
                swizzleG,
                swizzleB,
                swizzleA);

            if (IsDepthStencil(formatInfo.Format))
            {
                swizzleR = SwizzleComponent.Red;
                swizzleG = SwizzleComponent.Red;
                swizzleB = SwizzleComponent.Red;

                if (depthStencilMode == DepthStencilMode.Depth)
                {
                    swizzleA = SwizzleComponent.One;
                }
                else
                {
                    swizzleA = SwizzleComponent.Red;
                }
            }

            return(new TextureInfo(
                       address,
                       width,
                       height,
                       depthOrLayers,
                       levels,
                       samplesInX,
                       samplesInY,
                       stride,
                       isLinear,
                       gobBlocksInY,
                       gobBlocksInZ,
                       gobBlocksInTileX,
                       target,
                       formatInfo,
                       depthStencilMode,
                       swizzleR,
                       swizzleG,
                       swizzleB,
                       swizzleA));
        }
Пример #4
0
        /// <summary>
        /// Gets texture information from a texture descriptor.
        /// </summary>
        /// <param name="descriptor">The texture descriptor</param>
        /// <returns>The texture information</returns>
        private TextureInfo GetInfo(TextureDescriptor descriptor)
        {
            ulong address = Context.MemoryManager.Translate(descriptor.UnpackAddress());

            int width         = descriptor.UnpackWidth();
            int height        = descriptor.UnpackHeight();
            int depthOrLayers = descriptor.UnpackDepth();
            int levels        = descriptor.UnpackLevels();

            TextureMsaaMode msaaMode = descriptor.UnpackTextureMsaaMode();

            int samplesInX = msaaMode.SamplesInX();
            int samplesInY = msaaMode.SamplesInY();

            int stride = descriptor.UnpackStride();

            TextureDescriptorType descriptorType = descriptor.UnpackTextureDescriptorType();

            bool isLinear = descriptorType == TextureDescriptorType.Linear;

            Target target = descriptor.UnpackTextureTarget().Convert((samplesInX | samplesInY) != 1);

            // We use 2D targets for 1D textures as that makes texture cache
            // management easier. We don't know the target for render target
            // and copies, so those would normally use 2D targets, which are
            // not compatible with 1D targets. By doing that we also allow those
            // to match when looking for compatible textures on the cache.
            if (target == Target.Texture1D)
            {
                target = Target.Texture2D;
                height = 1;
            }
            else if (target == Target.Texture1DArray)
            {
                target = Target.Texture2DArray;
                height = 1;
            }

            uint format = descriptor.UnpackFormat();
            bool srgb   = descriptor.UnpackSrgb();

            if (!FormatTable.TryGetTextureFormat(format, srgb, out FormatInfo formatInfo))
            {
                if ((long)address > 0L && (int)format > 0)
                {
                    Logger.Error?.Print(LogClass.Gpu, $"Invalid texture format 0x{format:X} (sRGB: {srgb}).");
                }

                formatInfo = FormatInfo.Default;
            }

            int gobBlocksInY = descriptor.UnpackGobBlocksInY();
            int gobBlocksInZ = descriptor.UnpackGobBlocksInZ();

            int gobBlocksInTileX = descriptor.UnpackGobBlocksInTileX();

            SwizzleComponent swizzleR = descriptor.UnpackSwizzleR().Convert();
            SwizzleComponent swizzleG = descriptor.UnpackSwizzleG().Convert();
            SwizzleComponent swizzleB = descriptor.UnpackSwizzleB().Convert();
            SwizzleComponent swizzleA = descriptor.UnpackSwizzleA().Convert();

            DepthStencilMode depthStencilMode = GetDepthStencilMode(
                formatInfo.Format,
                swizzleR,
                swizzleG,
                swizzleB,
                swizzleA);

            if (formatInfo.Format.IsDepthOrStencil())
            {
                swizzleR = SwizzleComponent.Red;
                swizzleG = SwizzleComponent.Red;
                swizzleB = SwizzleComponent.Red;

                if (depthStencilMode == DepthStencilMode.Depth)
                {
                    swizzleA = SwizzleComponent.One;
                }
                else
                {
                    swizzleA = SwizzleComponent.Red;
                }
            }

            return(new TextureInfo(
                       address,
                       width,
                       height,
                       depthOrLayers,
                       levels,
                       samplesInX,
                       samplesInY,
                       stride,
                       isLinear,
                       gobBlocksInY,
                       gobBlocksInZ,
                       gobBlocksInTileX,
                       target,
                       formatInfo,
                       depthStencilMode,
                       swizzleR,
                       swizzleG,
                       swizzleB,
                       swizzleA));
        }