/*---------------------------------------------------------------------------* Copyright (C) Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. *---------------------------------------------------------------------------*/ // gx2Texture.h // // Declares texture-related types & functions for gx2 library. #ifndef _CAFE_GX2_TEXTURE_H_ #define _CAFE_GX2_TEXTURE_H_ #ifdef __cplusplus extern "C" { #endif // __cplusplus /// @addtogroup GX2TextureGroup /// @{ /// @addtogroup GX2TextureSurfaceGroup /// @{ // ----------------- // GX2Texture.h // !!!Note!!! - The GX2Texture structure is burned into .gtx file. // Altering parameters or changing their order may invalidate all existing content. /// \brief Completely describes a texture. /// /// In addition to GX2Surface, includes user fields to describe a texture. /// Also includes hardware register settings for the same purpose. /// It allows mip levels & array slices to be limited from what the surface /// specifies. This may be handy when not all images have been loaded yet. /// typedef struct _GX2Texture { /// main surface description GX2Surface surface; /// (user) first mip level that's available (usually 0) /// This value should be between 0 (the largest level) and surface.numMips-1. u32 viewFirstMip; /// (user) number of mip levels available (usually same as surface value). /// 0 implies 1. This value should be between 1 and (surface.numMips - viewFirstMip). u32 viewNumMips; /// (user) start slice in the array or 3D surface (usually 0) /// This value should be between 0 and surface.depth-1. u32 viewFirstSlice; /// (user) number of slices available (usually same as surface depth) /// 0 implies 1. This value should be between 1 and (surface.depth - viewFirstSlice). u32 viewNumSlices; /// (user) used to set the component swap (routing) selection GX2CompSel compSel; /// (calc) private, calculated by driver u32 _regs[GX2_NUM_TEXTURE_REGISTERS]; } GX2Texture; /// \brief Given a texture structure with user fields set, fill in register values. /// /// \param texture Ptr to texture structure to update. /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2InitTextureRegs(GX2Texture *texture); /// \brief Set the given texture to be used in a vertex shader. /// /// \param texture Ptr to texture structure to use; all fields & registers should already be initialized. /// \param textureUnitNumber Which texture unit to configure (from shader sampler var location). /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetVertexTexture(const GX2Texture *texture, u32 textureUnitNumber); /// \brief Set the given texture to be used in a geometry shader. /// /// \param texture Ptr to texture structure to use; all fields & registers should already be initialized. /// \param textureUnitNumber Which texture unit to configure (from shader sampler var location). /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetGeometryTexture(const GX2Texture *texture, u32 textureUnitNumber); /// \brief Set the given texture to be used in a pixel shader. /// /// \param texture Ptr to texture structure to use; all fields & registers should already be initialized. /// \param textureUnitNumber Which texture unit to configure (from shader sampler var location). /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetPixelTexture(const GX2Texture *texture, u32 textureUnitNumber); /// \brief Set the given texture to be used in a compute shader. /// /// \ingroup GX2ShaderComputeGroup /// /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders" /// /// \param texture Ptr to texture structure to use; all fields & registers should already be initialized. /// \param textureUnitNumber Which texture unit to configure (from shader sampler var location). /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetComputeTexture(const GX2Texture *texture, u32 textureUnitNumber); /// \brief Helper function to set up texture structure in a convenient way. /// /// \note The image pointers are set using \ref GX2InitTexturePtrs. /// /// \note Certain advanced options are set to defaults. You must /// be very careful if you wish to use non-default values /// for aa, use, tileMode, or swizzle. Please refer to /// \ref GX2TexturePage for more details. /// /// \param texture Ptr to texture structure to initialize. /// \param width Desired width for texture. /// \param height Desired height for texture. /// \param depth Desired depth for texture (use 1 for 2D). /// \param numMips Desired number of mipmap levels for texture (use 1 for base level only). /// \param format Desired surface format for texture. /// \param dim Desired dimensionality for texture. /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE void GX2InitTexture(GX2Texture *texture, u32 width, u32 height, u32 depth, u32 numMips, GX2SurfaceFormat format, GX2SurfaceDim dim) { const GX2CompSel dstSel[54] = { GX2_COMP_SEL_NONE, GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_NONE, // 00-03 GX2_COMP_SEL_NONE, GX2_COMP_SEL_X001, GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, // 04-07 GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, // 08-0b GX2_COMP_SEL_WZYX, GX2_COMP_SEL_X001, GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, // 0c-0f GX2_COMP_SEL_XY01, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, // 10-13 GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_NONE, // 14-17 GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_WZYX, // 18-1b GX2_COMP_SEL_XY01, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZW, // 1c-1f GX2_COMP_SEL_XYZW, GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, // 20-23 GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZ1, // 24-27 GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01, GX2_COMP_SEL_XYZ1, // 28-2b GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_NONE, GX2_COMP_SEL_XYZ1, // 2c-2f GX2_COMP_SEL_XYZ1, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, GX2_COMP_SEL_XYZW, // 30-33 GX2_COMP_SEL_X001, GX2_COMP_SEL_XY01 }; // 34-35 GX2_CHECK_ENUM_RANGE(format, GX2_SURFACE_FORMAT); GX2_CHECK_ENUM_RANGE(dim, GX2_SURFACE_DIM); // Set user surface values texture->surface.dim = dim; texture->surface.width = width; texture->surface.height = height; texture->surface.depth = depth; texture->surface.numMips = numMips; texture->surface.format = format; // Set most common default surface values texture->surface.aa = GX2_AA_MODE_1X; // if not 1X, must change dim field texture->surface.use = GX2_SURFACE_USE_TEXTURE; #ifdef GX2_ENABLE_FIX2197 texture->surface.tileMode = GX2_TILE_MODE_DEFAULT_FIX2197; #else texture->surface.tileMode = GX2_TILE_MODE_DEFAULT; #endif texture->surface.swizzle = 0; // Set typical view values texture->viewFirstMip = 0; texture->viewNumMips = numMips; texture->viewFirstSlice = 0; texture->viewNumSlices = depth; // Set default component selector texture->compSel = dstSel[(format) & 0x3f]; // Calculate the size, alignment, pitch, and mipOffset values GX2CalcSurfaceSizeAndAlignment(&texture->surface); // Now set up the registers based on those values GX2InitTextureRegs(texture); } /// \brief Function set up custom component selection. /// Requires calling GX2InitTextureRegs() afterwards. /// /// \param texture Ptr to texture structure to update. /// \param compSel New component swap selection value (see \ref GX2UTGroup). /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE void GX2InitTextureCompSel(GX2Texture *texture, GX2CompSel compSel) { texture->compSel = compSel; } /// \brief Helper function to set up texture image pointers. /// Does not require calling GX2InitTextureRegs() afterwards. /// /// \param texture Ptr to texture structure to update. /// \param imagePtr New image pointer value; points to level 0 image. /// \param mipPtr New mip pointer value; points to level 1+ image(s). /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE void GX2InitTexturePtrs(GX2Texture *texture, void *imagePtr, void *mipPtr) { texture->surface.imagePtr = imagePtr; if (texture->surface.numMips > 1) { if (mipPtr) { texture->surface.mipPtr = mipPtr; } else { texture->surface.mipPtr = (void *) ( (u32) imagePtr + texture->surface.mipOffset[0]); } } else { texture->surface.mipPtr = mipPtr; } } /// \brief Convert a linear format image into a tiled format texture. /// /// The present implementation uses CPU only (it is slow). /// The given texture structure should already be initialized, /// and it should have its imagePtr properly aligned & allocated as well. /// See also notes at \ref GX2CopySurface. /// /// \param dstTexture Ptr to texture structure to update. /// \param srcImagePtr Ptr to source linear image data. /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// GX2_INLINE void GX2TileTexture(GX2Texture* dstTexture, void *srcImagePtr) { GX2Surface srcSurf; ASSERT(dstTexture && srcImagePtr); srcSurf = dstTexture->surface; srcSurf.tileMode = GX2_TILE_MODE_LINEAR_SPECIAL; srcSurf.imagePtr = srcImagePtr; GX2CalcSurfaceSizeAndAlignment(&srcSurf); // Make sure the source texture data is in memory GX2Invalidate(GX2_INVALIDATE_CPU_TEXTURE, srcImagePtr, srcSurf.imageSize); GX2CopySurface(&srcSurf, 0, 0, &dstTexture->surface, 0, 0); } /// @} /// @addtogroup GX2TextureSamplerGroup /// @{ //---------------------------------------------------------------------- // Texture Samplers /// \brief Structure to contain all sampler (register) settings. /// typedef struct _GX2Sampler { u32 samplerReg[3]; // sampler (filtering) related settings } GX2Sampler; /// \brief Initialize a texture sampler with some basic settings and common defaults /// /// By default, Z and Mip filters are set to point sampling, max aniso is set to 1, /// border type is set to transparent black, LOD is unrestricted/unchanged, high /// precision filter is off, and perf options are default. Use the other sampler APIs /// to change these values. /// /// \param sampler Ptr to texture sampler structure to initialize. /// \param clampAll Clamping mode for X/Y/Z dimensions. /// \param minMagFilter Minification and magnification filters to use for X & Y dimensions. /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2InitSampler(GX2Sampler *sampler, GX2TexClamp clampAll, GX2TexXYFilterType minMagFilter); /// \brief Function to change sampler clamp settings. /// /// \param sampler Ptr to texture sampler structure to update. /// \param clampX Texture coordinate clamp option for X dimension. /// \param clampY Texture coordinate clamp option for Y dimension. /// \param clampZ Texture coordinate clamp option for Z dimension. /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2InitSamplerClamping(GX2Sampler *sampler, GX2TexClamp clampX, GX2TexClamp clampY, GX2TexClamp clampZ); /// \brief Function to change sampler XY filter settings. /// /// \param sampler Ptr to texture sampler structure to update. /// \param magFilter Sampling to perform when images are magnified. /// \param minFilter Sampling to perform when images are minified. /// \param maxAniso Maximum level of anisotropic filtering to apply. Use 1:1 to disable aniso filtering. /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2InitSamplerXYFilter(GX2Sampler *sampler, GX2TexXYFilterType magFilter, GX2TexXYFilterType minFilter, GX2TexAnisoRatio maxAniso); /// \brief Function to change sampler Z & mip filter settings. /// /// \param sampler Ptr to texture sampler structure to update. /// \param zFilter Sampling to perform across image Z planes. /// \param mipFilter Sampling to perform across mip levels. /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2InitSamplerZMFilter(GX2Sampler *sampler, GX2TexZFilterType zFilter, GX2TexMipFilterType mipFilter); /// \brief Function to change sampler LOD settings. /// /// LOD is calculated as a fractional number based on the texel:pixel ratio. /// The whole part of the value determines which mip level or levels are /// accessed, and the fraction determines the interpolation between them /// (for trilinear filtering) or the transition point (for bilinear). /// /// \note This function allows additional restrictions on access to mip levels /// beyond what the texture itself specifies. It is okay to leave these /// values at their maximum extents. /// /// \note The valid LOD range is 0 ... 15.999. /// \note The valid bias range is -32 ... 31.999. /// /// \note The sampler's LOD is relative to the texture's view, defined by viewFirstMip /// and viewNumMips. LOD 0 is the largest and most detailed mip level allowed /// by the view. maxLOD should be greater than or equal to minLOD. /// To limit the LOD to a single mipmap both minLOD and maxLOD should be set /// to the same value. /// /// \param sampler Ptr to texture sampler structure to update. /// \param minLOD Lower bound for mip LOD level calculation. The is relative to the texture's view. /// \param maxLOD Upper bound for mip LOD level calculation. This should be >= minLOD. /// This is relative to the texture's view. /// \param LODBias A bias value for LOD applied prior to applying min/max constraints. /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2InitSamplerLOD(GX2Sampler *sampler, f32 minLOD, f32 maxLOD, f32 LODBias); /// \brief Sets the type of border used by sampler /// \note It's better to avoid using the register color type, as setting /// those registers requires a pipeline stall. /// /// \param sampler Ptr to texture sampler structure to update. /// \param border Type of border color to use. /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2InitSamplerBorderType(GX2Sampler *sampler, GX2TexBorderType border); /// \brief Function to change sampler rounding modes. /// /// \param sampler Ptr to texture sampler structure to update. /// \param roundingMode Texture coordinate rounding mode. /// /// Setting the rounding mode effects how texture coordinates are truncated. /// The default GX2 behavior is \ref GX2_ROUNDING_MODE_ROUND_TO_EVEN. /// /// This is provided to work around an issue where point-sampled textures /// may unexpectedly wrap when a given mipmap level is magnified more than /// 64 times its original size. In this case, \ref GX2_ROUNDING_MODE_TRUNCATE /// should be used. /// /// \warning Setting \ref GX2_ROUNDING_MODE_TRUNCATE should only be set when /// the following are true. See \ref GX2TextureCoordinateRoundingSect /// for more details. /// -# \c minFilter and \c magFilter are \ref GX2_TEX_XY_FILTER_POINT /// -# \c clampX, \c clampY or \c clampZ are \ref GX2_TEX_CLAMP_WRAP /// /// \warning Changing the rounding mode to \ref GX2_ROUNDING_MODE_TRUNCATE will /// affect bilinear interpolation. It is recommended that a separate /// sampler is allocated for this purpose to avoid unintended sampling /// differences. /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2InitSamplerRoundingMode(GX2Sampler *sampler, GX2RoundingModeType roundingMode); /// \brief Set the border color to be used by vertex-shader texture sampler. /// /// \note Calling this function will result in a graphics pipeline stall. /// Calling it too frequently will result in a loss of performance. /// /// \param samplerUnitNumber Which sampler unit to configure (from shader sampler var location). /// \param red Red color component value for border color (0.0 - 1.0). /// \param green Green color component value for border color (0.0 - 1.0). /// \param blue Blue color component value for border color (0.0 - 1.0). /// \param alpha Alpha color component value for border color (0.0 - 1.0). /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetVertexSamplerBorderColor(u32 samplerUnitNumber, f32 red, f32 green, f32 blue, f32 alpha); /// \brief Set the border color to be used by geometry-shader texture sampler. /// /// \note Calling this function will result in a graphics pipeline stall. /// Calling it too frequently will result in a loss of performance. /// /// \param samplerUnitNumber Which sampler unit to configure (from shader sampler var location). /// \param red Red color component value for border color (0.0 - 1.0). /// \param green Green color component value for border color (0.0 - 1.0). /// \param blue Blue color component value for border color (0.0 - 1.0). /// \param alpha Alpha color component value for border color (0.0 - 1.0). /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetGeometrySamplerBorderColor(u32 samplerUnitNumber, f32 red, f32 green, f32 blue, f32 alpha); /// \brief Set the border color to be used by pixel-shader texture sampler. /// /// \note Calling this function will result in a graphics pipeline stall. /// Calling it too frequently will result in a loss of performance. /// /// \param samplerUnitNumber Which sampler unit to configure (from shader sampler var location). /// \param red Red color component value for border color (0.0 - 1.0). /// \param green Green color component value for border color (0.0 - 1.0). /// \param blue Blue color component value for border color (0.0 - 1.0). /// \param alpha Alpha color component value for border color (0.0 - 1.0). /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetPixelSamplerBorderColor(u32 samplerUnitNumber, f32 red, f32 green, f32 blue, f32 alpha); /// \brief Set the border color to be used by compute-shader texture sampler. /// \ingroup GX2ShaderComputeGroup /// /// \note Calling this function will result in a graphics pipeline stall. /// Calling it too frequently will result in a loss of performance. /// /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders" /// /// \param samplerUnitNumber Which sampler unit to configure (from shader sampler var location). /// \param red Red color component value for border color (0.0 - 1.0). /// \param green Green color component value for border color (0.0 - 1.0). /// \param blue Blue color component value for border color (0.0 - 1.0). /// \param alpha Alpha color component value for border color (0.0 - 1.0). /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetComputeSamplerBorderColor(u32 samplerUnitNumber, f32 red, f32 green, f32 blue, f32 alpha); /// \brief Sets the depth compare function when a shadow-type sampler is applied /// /// \note This does not make the sampler into a shadow type; that is /// decided by how the sampler is declared in the shader. /// /// \param sampler Ptr to texture sampler structure to update. /// \param depthCompare Which depth comparison function to use. /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2InitSamplerDepthCompare(GX2Sampler *sampler, GX2CompareFunction depthCompare); /// \brief Used to tweak various advanced filtering performance options /// /// \param sampler Ptr to texture sampler structure to update. /// \param highPrecision If true, forces all formats to be converted to 32 bit float components, 2 channels/clock. /// \param perfMip Selects one of 8 lookup tables to adjust the linear mipmap transition performance/quality tradeoff. /// \param perfZ Selects one of 4 lookup tables to adjust the linear Z filter performance/quality tradeoff. /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2InitSamplerFilterAdjust(GX2Sampler *sampler, GX2Boolean highPrecision, GX2TexMipPerfType perfMip, GX2TexZPerfType perfZ); /// \brief Used to tweak various advanced filtering aniso/LOD options /// /// The valid bias range is 0 ... 1.999. /// /// \param sampler Ptr to texture sampler structure to update. /// \param anisoBias A number that is subtracted from the computed aniso ratio, reducing the number of samples taken. /// \param lodUsesMinorAxis Forces the hardware to use minor axis for LOD calculation (for special shadow buffer path). /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2InitSamplerLODAdjust(GX2Sampler *sampler, f32 anisoBias, GX2Boolean lodUsesMinorAxis); /// \brief Set the sampler to be used by vertex shader. /// /// \param sampler Ptr to texture sampler structure to use. /// \param samplerUnitNumber Which sampler unit to configure (from shader sampler var location). /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetVertexSampler(const GX2Sampler *sampler, u32 samplerUnitNumber); /// \brief Set the sampler to be used by geometry shader. /// /// \param sampler Ptr to texture sampler structure to use. /// \param samplerUnitNumber Which sampler unit to configure (from shader sampler var location). /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetGeometrySampler(const GX2Sampler *sampler, u32 samplerUnitNumber); /// \brief Set the sampler to be used by pixel shader. /// /// \param sampler Ptr to texture sampler structure to use. /// \param samplerUnitNumber Which sampler unit to configure (from shader sampler var location). /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetPixelSampler(const GX2Sampler *sampler, u32 samplerUnitNumber); /// \brief Set the sampler to be used by compute shader. /// \ingroup GX2ShaderComputeGroup /// /// For more information about Compute Shaders see \ref GX2ComputePage "GX2 Compute Shaders" /// /// \param sampler Ptr to texture sampler structure to use. /// \param samplerUnitNumber Which sampler unit to configure (from shader sampler var location). /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2SetComputeSampler(const GX2Sampler *sampler, u32 samplerUnitNumber); /// @} /// @} #ifdef __cplusplus } #endif // __cplusplus #endif // _CAFE_GX2_TEXTURE_H_