/*---------------------------------------------------------------------------* 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. *---------------------------------------------------------------------------*/ // ----------------------------------------------------------------------------- // demoGfx.h // // ----------------------------------------------------------------------------- #ifndef __DEMO_GFX_H__ #define __DEMO_GFX_H__ #include #include #include #include #ifdef __cplusplus extern "C" { #endif /// @addtogroup demoRender /// @{ /// \brief The maximum length allowed for the asset directory passed with DEMO_ASSETS_DIR #define MAX_ASSET_DIR_LEN 1000 /// \brief The maximum total length allowed for the asset's path in DEMOGfxLoadAssetFile #define MAX_ASSET_DIR_FULL_LEN 2000 /// \brief Default color buffer for DEMOGfx (global) extern GX2ColorBuffer DEMOColorBuffer; /// \brief Default depth buffer for DEMOGfx (global) extern GX2DepthBuffer DEMODepthBuffer; /// \brief Default context state ptr for DEMOGfx (global) extern GX2ContextState *DEMOContextState; /// \brief Structure used to define an instance of DEMOGfx typedef struct { /// \brief Context state ptr for DEMOGfx (instance) GX2ContextState *contextState; } DEMOGfxInstance; /// \brief Memory allocator that allocates MEM1 for graphics /// /// This function calls \ref GX2NotifyMemAlloc which enables /// various (future) debugging features. void *DEMOGfxAllocMEM1(u32 size, u32 align); /// \brief Memory allocator that allocates from the foreground bucket for graphics /// /// This function calls \ref GX2NotifyMemAlloc which enables /// various (future) debugging features. void *DEMOGfxAllocBucket(u32 size, u32 align); /// \brief Memory allocator that allocates MEM2 for graphics /// /// This function calls \ref GX2NotifyMemAlloc which enables /// various (future) debugging features. void *DEMOGfxAllocMEM2(u32 size, u32 align); /// \brief Free MEM1 /// void DEMOGfxFreeMEM1(void * ptr); /// \brief Free memory from the foreground bucket. /// void DEMOGfxFreeBucket(void * ptr); /// \brief Free MEM2 /// void DEMOGfxFreeMEM2(void * ptr); /// \brief Initializes GX2 & AVM; sets up default render/depth/scan buffers. /// /// It must be called before calling any other GX2 functions.\n /// The following arguments can be specified:\n /// /// -DEMO_WIDTH=n (set TV RT width to n) \n /// -DEMO_HEIGHT=n (set TV RT height to n) \n /// -DEMO_CB_FORMAT=str (set TV color buffer format to 8_8_8_8, 10_10_10_2, 2_10_10_10, 16_16_16_16F, or 32_32_32_32F) \n /// -DEMO_SCAN_FORMAT=str (set TV scan-out buffer format to 8_8_8_8, 10_10_10_2, or 2_10_10_10) \n /// -DEMO_DB_FORMAT=str (set TV depth buffer format to 16, 32F, 8_24, X24_8_32F) \n /// -DEMO_AA_MODE=n (set TV AA mode to 0/1/2/3) \n /// -DEMO_FONT_DISABLE (disables drawing of DEMOFont API)\n /// /// Set up defaults for all options are (1280/720/8_8_8_8/32F/no AA).\n /// Unknown args are ignored, and the arg list is left unchanged.\n /// /// To configure the DRC, please see \ref DEMODRCInit. /// /// This function will call DEMOGfxMem1HeapInit(), which will allocate all available memory from the MEM1 /// frame heap and initialize the expanded heap used by DEMOGfxAllocMEM1(). /// /// \param argc number of arguments /// \param argv argument values /// /// \retval A pointer to the instance created by this function DEMOGfxInstance* DEMOGfxInit(int argc, char *argv[]); /// \brief Releases allocated buffers and shuts down GX2. /// void DEMOGfxShutdown(void); /// \brief Releases foreground only resources and GX2. /// void DEMOGfxReleaseForeground(void); /// \brief Re-acquires GX2 resources and prepares for rendering. /// void DEMOGfxAcquiredForeground(void); /// \brief Get demo graphics running state /// /// \retval TRUE if \ref DEMOGfxInit() has been called; false otherwise. BOOL DEMOGfxIsRunning(void); /// Set demo gfx context to current. /// Need to call this API before Drawing with demo gfx context created in DEMOGfxInit. void DEMOGfxSetContextState(void); /// \brief Currently, this function waits for the previously rendered frame to appear. /// Functionality may change in the future. /// void DEMOGfxBeforeRender(void); /// \brief Swaps the video (scan) buffers, requests new frame to be displayed. /// Note that it does not wait for the new frame to appear. /// void DEMOGfxDoneRender(void); /// \brief Wrapper for GX2DrawDone that works in the background and if /// DEMOGfx has not been initialized. /// void DEMOGfxDrawDone(void); /// \brief Synchronize rendering with video display/swap in a specific way /// /// This is a very important function that every app should include in some fashion. /// It prevents the CPU and GPU from running too far ahead of the video display. /// This function shows an example of how to specify a precise amount of /// latency with respect to when video swap occurs. /// /// \param depth Number of frames rendering may run ahead of display /// \param percent Additional fraction of a frame to wait after specified swap /// (expressed as an integer 0...100 percent of the swap interval time) void DEMOGfxWaitForSwap(u32 depth, u32 percent); /// \brief Returns a string with the name of a given GX2 attrib format. /// const char *DEMOGfxGetAttribFormatName(GX2AttribFormat format); /// \brief Returns a string with the name of a given GX2 surface format. /// const char *DEMOGfxGetSurfaceFormatName(GX2SurfaceFormat format); /// \brief A helper function to reset render targets to DEMO buffers. /// GX2_INLINE void DEMOGfxSetDefaultRenderTarget(void) { GX2UTDebugTagIndent("DEMOGfxSetDefaultRenderTarget()"); GX2SetColorBuffer(&DEMOColorBuffer, GX2_RENDER_TARGET_0); GX2SetDepthBuffer(&DEMODepthBuffer); GX2UTDebugTagUndent(); } /// \brief Setting up special color buffer (e.g) multi-layered frame buffer /// /// \param colorBuffer Ptr to color buffer structure to initialize. /// \param dim Desired dim for color buffer. /// \param width Desired width for color buffer. /// \param height Desired height for color buffer. /// \param depth Desired depth for color buffer. /// \param format Desired surface format for color buffer. /// \param aa Desired AA mode for color buffer. /// GX2_INLINE void DEMOGfxInitColorBufferEx(GX2ColorBuffer *colorBuffer, GX2SurfaceDim dim, u32 width, u32 height, u32 depth, GX2SurfaceFormat format, GX2AAMode aa) { GX2UTDebugTagIndent("DEMOGfxInitColorBufferEx()"); GX2_CHECK_ENUM_RANGE(dim, GX2_SURFACE_DIM) GX2_CHECK_ENUM_RANGE(format, GX2_SURFACE_FORMAT) GX2_CHECK_ENUM_RANGE(aa, GX2_AA_MODE) colorBuffer->surface.dim = dim; colorBuffer->surface.width = width; colorBuffer->surface.height = height; colorBuffer->surface.depth = depth; colorBuffer->surface.numMips = 1; // 1 means base level only colorBuffer->surface.format = format; colorBuffer->surface.aa = aa; colorBuffer->surface.use = GX2_SURFACE_USE_COLOR_BUFFER_TEXTURE; colorBuffer->surface.tileMode = GX2_TILE_MODE_DEFAULT; colorBuffer->surface.swizzle = 0; colorBuffer->viewMip = 0; colorBuffer->viewFirstSlice = 0; colorBuffer->viewNumSlices = depth; GX2CalcSurfaceSizeAndAlignment(&colorBuffer->surface); GX2InitColorBufferRegs(colorBuffer); GX2UTDebugTagUndent(); } /// \brief Setting up special depth buffer (e.g) multi-layered frame buffer /// /// \param depthBuffer Ptr to depth buffer structure to initialize. /// \param dim Desired dim for depth buffer. /// \param width Desired width for depth buffer. /// \param height Desired height for depth buffer. /// \param depth Desired depth for depth buffer. /// \param format Desired surface format for depth buffer. /// \param aa Desired AA mode for depth buffer. /// GX2_INLINE void DEMOGfxInitDepthBufferEx(GX2DepthBuffer *depthBuffer, GX2SurfaceDim dim, u32 width, u32 height, u32 depth, GX2SurfaceFormat format, GX2AAMode aa) { GX2UTDebugTagIndent("DEMOGfxInitDepthBufferEx()"); GX2_CHECK_ENUM_RANGE(dim, GX2_SURFACE_DIM) GX2_CHECK_ENUM_RANGE(format, GX2_SURFACE_FORMAT) GX2_CHECK_ENUM_RANGE(aa, GX2_AA_MODE) depthBuffer->surface.dim = dim; depthBuffer->surface.width = width; depthBuffer->surface.height = height; depthBuffer->surface.depth = depth; depthBuffer->surface.numMips = 1; // 1 means base level only depthBuffer->surface.format = format; depthBuffer->surface.aa = aa; depthBuffer->surface.use = ((format==GX2_SURFACE_FORMAT_D_D24_S8_UNORM) || (format==GX2_SURFACE_FORMAT_D_D24_S8_FLOAT)) ? GX2_SURFACE_USE_DEPTH_BUFFER : GX2_SURFACE_USE_DEPTH_BUFFER_TEXTURE; depthBuffer->surface.tileMode = GX2_TILE_MODE_DEFAULT; depthBuffer->surface.swizzle = 0; depthBuffer->viewMip = 0; depthBuffer->viewFirstSlice = 0; depthBuffer->viewNumSlices = depth; depthBuffer->clearDepth = 1.0f; depthBuffer->clearStencil = 0; GX2CalcSurfaceSizeAndAlignment(&depthBuffer->surface); GX2InitDepthBufferRegs(depthBuffer); GX2UTDebugTagUndent(); } /// \brief Initializes the expanded heap for MEM1 /// /// This function will allocate all available memory from the MEM1 frame heap and /// initialize the expanded heap used by \ref DEMOGfxAllocMEM1. /// This is normally called by \ref DEMOGfxInit. /// A real game shouldn't use the expanded heap to manage MEM1, but for demos it should be fine. /// void DEMOGfxMem1HeapInit(void); /// \brief Destroys the expanded heap for MEM1 /// /// This function will destroy the expanded heap used by DEMOGfxAllocMEM1(). /// This is normally called by \ref DEMOGfxShutdown. /// void DEMOGfxMem1HeapDestroy(void); /// \brief Initializes the expanded heap for the foreground bucket /// /// This function will initialize the expanded heap used by DEMOGfxAllocBucket(). /// This is normally called by \ref DEMOGfxInit. /// void DEMOGfxBucketHeapInit(void); /// \brief Destroys the expanded heap for the foreground bucket /// /// This function will destroy the expanded heap used by DEMOGfxAllocBucket(). /// This is normally called by \ref DEMOGfxShutdown. /// void DEMOGfxBucketHeapDestroy(void); /// \brief Creates a new instance of DEMOGfx /// /// This will create a new instance, in addition to setting the instance. /// This is called by \ref DEMOGfxInit. /// DEMOGfxInstance* DEMOGfxAddInstance(void); /// \brief Deletes an instance of DEMOGfx /// /// This is called by \ref DEMOGfxShutdown. /// /// \param instance The instance to be deleted /// void DEMOGfxDeleteInstance(DEMOGfxInstance *instance); /// \brief Sets the instance of DEMOGfx /// /// \param instance The instance to use /// void DEMOGfxSetInstance(DEMOGfxInstance *instance); /// \brief Gets the instance of DEMOGfx DEMOGfxInstance* DEMOGfxGetInstance(void); /// \brief Reads an asset from the asset directory into an automatically created and allocated buffer. /// /// File is automatically closed after it's read from. /// Call \ref DEMOFree to free this buffer. /// /// This function is a wrapper for \ref DEMOFSSimpleRead. /// /// \param path File string name to read (full path is \\) /// \param len Length of file returned here /// void* DEMOGfxLoadAssetFile(const char* path, u32* len); /// \brief Open an asset file for reading. /// /// Opens a file for reading. /// /// This function is a wrapper for \ref DEMOFSOpenFile. /// /// \param path Pointer to file name to open /// \param info Pointer to file information to use /// /// \retval DEMO_FS_RESULT_OK if it is ok. /// \retval DEMO_FS_RESULT_PERMISSION if it is not permitted to open current file. /// \retval DEMO_FS_RESULT_CORRUPTION if a file is corrupted. /// \retval DEMO_FS_FATAL_ERROR if a fatal error occurs during a read, the function returns. s32 DEMOGfxOpenAssetFile(const char* path, DEMOFSFileInfo* info); /// \brief Gets the size of the opened asset file. /// /// Gets the size of a file opened with \ref DEMOGfxOpenAssetFile. /// /// This function is a wrapper for \ref DEMOFSGetLength. /// /// \param fileInfo File information of the file /// \param length The file size. As a return value, this size may not always be a multiple of 32. For this reason, when preparing buffers for reading files, this value must be rounded up to a multiple of 32 /// /// \retval DEMO_FS_RESULT_OK if it is successed. /// \retval DEMO_FS_RESULT_FATAL_ERROR if a fatal error occurs during a read, the function returns. s32 DEMOGfxGetAssetFileLength(const DEMOFSFileInfo* fileInfo, u32* length); /// \brief Synchronously reads from the opened asset file. /// /// Synchronously reads data from a file. First opens the file with the DEMOGfxOpenAssetFile function. /// /// This function is a wrapper for \ref DEMOFSRead. /// /// \param fileInfo File information of the file. /// \param addr Buffer address. Must be \c PPC_IO_BUFFER_ALIGN byte aligned. /// \param length Number of bytes to read. Must be a multiple of 32. /// \param offset File position to start reading from. Must be a multiple of 4. /// /// \retval DEMO_FS_RESULT_OK if it is ok. /// \retval DEMO_FS_RESULT_ACCESS if it is no right to access file. /// \retval DEMO_FS_RESULT_CORRUPTION if a file is corrupted. /// \retval DEMO_FS_FATAL_ERROR if a fatal error occurs during a read, the function returns. s32 DEMOGfxReadAssetFile(DEMOFSFileInfo* fileInfo, void* addr, s32 length, s32 offset); /// \brief Closes the asset file. /// /// Closes the specified file. /// if the FS library is not expecting a call (for example, during transfer) to the DEMOGfxCloseAssetFile function, the call to the function takes time. /// Ensure that this situation doesn't occur. /// (Namely, when calling DEMOGfxCloseAssetFile, make sure the transfer is complete.) /// /// This function is a wrapper for \ref DEMOFSCloseFile. /// /// \param fileInfo File information for the file to close. /// /// \retval DEMO_FS_RESULT_OK if it is ok. /// \retval DEMO_FS_RESULT_CORRUPTION if a file is corrupted. /// \retval DEMO_FS_FATAL_ERROR if a fatal error occurs during a read, the function returns. s32 DEMOGfxCloseAssetFile(DEMOFSFileInfo* fileInfo); /// \brief Reads an asset from the asset directory into an automatically created and allocated buffer. /// /// This buffer is aligned with alignSize. /// File is automatically closed after it's read from. /// Call \ref DEMOFree to free this buffer. /// /// This function is a wrapper for \ref DEMOFSSimpleReadAlign. /// /// \param path File string name to read (full path is \\) /// \param len Length of file returned here /// \param alignSize The alignment to use /// void* DEMOGfxLoadAssetFileAlign(const char* path, u32* len, u32 alignSize); /// \brief Scans directory for all the assets in it. /// /// This returns a list of the names of all the files in a directory. Subdirectories /// are automatically excluded. Pathnames are returned, suitable for passing directly /// to \ref DEMOGfxOpenAssetFile or \ref DEMOGfxLoadAssetFile. /// /// This function is a wrapper for \ref DEMOFSSimpleScanDir. /// /// \param path Directory name /// \param pFileCount Number of files in the directory /// \param maxFiles Maximum number of file names to return from this function /// \param ppFileNames Returned array of names of files. The base array must be specified /// by the caller. (e.g char *ppFileNames[maxFiles]; ) /// Each non null string is allocated using \ref DEMOAlloc in this routine. /// Call \ref DEMOFree in caller to free them. /// \return DEMO_FS_RESULT_OK on success, or error value. s32 DEMOGfxScanAssetDir(const char *path, u32 *pFileCount, u32 maxFiles, char** ppFileNames); /// \brief Determines whether a file exists /// /// This function can be used prior to \ref DEMOGfxLoadAssetFile to error out without /// asserting if the file does not exist. /// /// This function is a wrapper for \ref DEMOFSFileExists. /// /// \param path Pointer to the name of the file /// /// \retval TRUE if the file exists. /// \retval FALSE if the file does not exist. BOOL DEMOGfxFileExists(const char* path); /// \brief Structure used to manage GPU Tasks typedef struct _DEMOGfxGPUTask { void *pDLPatchLoc; /// pointer to the nop patch space within the dl epilogue u64 timeVal; /// our key, used for lookups struct _DEMOGfxGPUTask *next; /// simple linked list } DEMOGfxGPUTask; /// \brief Memory location used by GPU Task Management extern u32 gDemoGfxGPUFence; /// \brief Timestamp used by GPU Task Management extern u64 *gpDemoGfxGPUTs; /// \brief Bit used to differentiate GPUTask TimeStamps, set for End TimeStamp #define DEMO_GPU_TASK_END_TS (1ull << 63ull) /// \brief Given a display list, writes the DEMOGfxGPUTask prologue /// /// \retval NULL if GPU Task Creation fails /// \retval Address of new GPU Task if successful /// DEMOGfxGPUTask* DEMOGfxBeginGPUTask(); /// \brief Given a display list, writes the DEMOGfxGPUTask epilogue /// void DEMOGfxEndGPUTask(); /// \brief Insert a call to a new GPU Task in the epilogue of the task currently /// being executed by the GPU /// /// \param pDisplayList Display list to be executed /// \param byteSize Size of the display list /// void DEMOGfxInsertGPUTask(void *pDisplayList, u32 byteSize); /// \brief Frees one GPUTaskHandle, used to prune DEMO's list of GPU Tasks /// /// \param pTask GPU Task to be freed /// void DEMOGfxFreeGPUTask(DEMOGfxGPUTask *pTask); /// \brief Frees entire GPUTaskHandle list, used to clobber DEMO's list of GPU Tasks /// void DEMOGfxFreeGPUTasks(void); /// @} // demoGfx #ifdef __cplusplus } #endif #endif /// __DEMO_GFX_H__