/*---------------------------------------------------------------------------* 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. *---------------------------------------------------------------------------*/ ////=========================================================================== /// DEMOGfd.c /// /// This is gfd file interface code for the DEMO library. /// ////=========================================================================== #include // Read Vertex Shader from buffer BOOL DEMOGFDReadVertexShader(GX2VertexShader **ppShader, u32 index, const void *pData) { GX2VertexShader *pHeader; void *pProgram; u32 ret; u32 headerSize; u32 programSize; // Check inputs if(pData == NULL || ppShader == NULL) { return FALSE; } // Check index number of shaders if(index >= GFDGetVertexShaderCount(pData)) { return FALSE; } // Get the size headerSize = GFDGetVertexShaderHeaderSize(index, pData); programSize = GFDGetVertexShaderProgramSize(index, pData); if(!headerSize || !programSize) return FALSE; // Alloc header pHeader = (GX2VertexShader *)DEMOAllocEx(headerSize, PPC_IO_BUFFER_ALIGN); GX2RBuffer shaderProgram; GX2UTCreateShaderProgram(&shaderProgram, programSize); pProgram = GX2RLockBuffer(&shaderProgram); // Get the shader structure and program // from file buffer into user aligned buffer which created above ret = GFDGetVertexShader(pHeader, pProgram, index, pData); if (ret) { GX2RUnlockBuffer(&shaderProgram); pHeader->shaderPtr = NULL; pHeader->shaderProgram = shaderProgram; *ppShader = pHeader; } else { GX2RUnlockBufferEx(&shaderProgram, GX2R_OPTION_NO_INVALIDATE); OSReport("Warning: Invalid Vertex Shader :%d", ret); // Free if fail if(pHeader) DEMOFree(pHeader); GX2RDestroyBuffer(&shaderProgram); } return ret; } // Read Pixel Shader from buffer BOOL DEMOGFDReadPixelShader(GX2PixelShader **ppShader, u32 index, const void *pData) { GX2PixelShader *pHeader; void *pProgram; u32 ret; u32 headerSize; u32 programSize; // Check inputs if(pData == NULL || ppShader == NULL) { OSReport("DEMOGFDReadPixelShader: NULL inputs\n"); return FALSE; } // Check index number of shaders if(index >= GFDGetPixelShaderCount(pData)) { OSReport("DEMOGFDReadPixelShader: bad index\n"); return FALSE; } // Get the size headerSize = GFDGetPixelShaderHeaderSize(index, pData); programSize = GFDGetPixelShaderProgramSize(index, pData); if(!headerSize || !programSize) { OSReport("DEMOGFDReadPixelShader: header or program size is 0\n"); return FALSE; } // Alloc header pHeader = (GX2PixelShader *)DEMOAllocEx(headerSize, PPC_IO_BUFFER_ALIGN); // Alloc shader program GX2RBuffer shaderProgram; GX2UTCreateShaderProgram(&shaderProgram, programSize); pProgram = GX2RLockBuffer(&shaderProgram); // Get the shader structure and program // from file buffer into user aligned buffer which created above ret = GFDGetPixelShader(pHeader, pProgram, index, pData); if (ret) { GX2RUnlockBuffer(&shaderProgram); pHeader->shaderPtr = NULL; pHeader->shaderProgram = shaderProgram; *ppShader = pHeader; } else { GX2RUnlockBufferEx(&shaderProgram, GX2R_OPTION_NO_INVALIDATE); OSReport("Warning: Invalid Pixel Shader :%d\n", ret); // Free if fail if(pHeader) DEMOFree(pHeader); GX2RDestroyBuffer(&shaderProgram); } return ret; } // Read Geometry Shader from buffer BOOL DEMOGFDReadGeometryShader(GX2GeometryShader **ppShader, u32 index, const void *pData) { GX2GeometryShader *pHeader; void *pProgram; void *pCopyProgram; u32 ret; u32 headerSize; u32 programSize; u32 copyProgramSize; // Check inputs if(pData == NULL || ppShader == NULL) { return FALSE; } // Check index number of shaders if(index >= GFDGetGeometryShaderCount(pData)) { return FALSE; } // Get the size headerSize = GFDGetGeometryShaderHeaderSize(index, pData); programSize = GFDGetGeometryShaderProgramSize(index, pData); copyProgramSize = GFDGetGeometryShaderCopyProgramSize(index, pData); if(!headerSize || !programSize) return FALSE; // Alloc header pHeader = (GX2GeometryShader *)DEMOAllocEx(headerSize, PPC_IO_BUFFER_ALIGN); // Create shader program buffer GX2RBuffer shaderProgram; GX2UTCreateShaderProgram(&shaderProgram, programSize); // Alloc copy shader program (Must be aligned on 256 byte boundary.) GX2RBuffer copyShaderProgram; GX2UTCreateShaderProgram(©ShaderProgram, copyProgramSize); pProgram = GX2RLockBuffer(&shaderProgram); pCopyProgram = GX2RLockBuffer(©ShaderProgram); // Get the shader structure and program // from file buffer into user aligned buffer which created above ret = GFDGetGeometryShader(pHeader, pProgram, pCopyProgram, index, pData); if(ret) { GX2RUnlockBuffer(&shaderProgram); GX2RUnlockBuffer(©ShaderProgram); pHeader->shaderPtr = NULL; pHeader->shaderProgram = shaderProgram; pHeader->copyShaderPtr = NULL; pHeader->copyShaderProgram = copyShaderProgram; *ppShader = pHeader; } else { OSReport("Warning: Invalid Geometry Shader :%d", ret); // Free if fail if(pHeader) DEMOFree(pHeader); GX2RUnlockBufferEx(&shaderProgram, GX2R_OPTION_NO_INVALIDATE); GX2RUnlockBufferEx(©ShaderProgram, GX2R_OPTION_NO_INVALIDATE); GX2RDestroyBuffer(&shaderProgram); GX2RDestroyBuffer(©ShaderProgram); } return ret; } // Read Compute Shader from buffer BOOL DEMOGFDReadComputeShader(GX2ComputeShader **ppShader, u32 index, const void *pData) { GX2ComputeShader *pHeader; void *pProgram; u32 ret; u32 headerSize; u32 programSize; // Check inputs if(pData == NULL || ppShader == NULL) { return FALSE; } // Check index number of shaders if(index >= GFDGetComputeShaderCount(pData)) { return FALSE; } // Get the size headerSize = GFDGetComputeShaderHeaderSize(index, pData); programSize = GFDGetComputeShaderProgramSize(index, pData); if(!headerSize || !programSize) return FALSE; // Alloc header pHeader = (GX2ComputeShader *)DEMOAllocEx(headerSize, PPC_IO_BUFFER_ALIGN); GX2RBuffer shaderProgram; GX2UTCreateShaderProgram(&shaderProgram, programSize); pProgram = GX2RLockBuffer(&shaderProgram); // Get the shader structure and program // from file buffer into user aligned buffer which created above ret = GFDGetComputeShader(pHeader, pProgram, index, pData); if (ret) { GX2RUnlockBuffer(&shaderProgram); pHeader->shaderPtr = NULL; pHeader->shaderProgram = shaderProgram; *ppShader = pHeader; } else { GX2RUnlockBufferEx(&shaderProgram, GX2R_OPTION_NO_INVALIDATE); OSReport("Warning: Invalid Compute Shader :%d", ret); // Free if fail if(pHeader) DEMOFree(pHeader); GX2RDestroyBuffer(&shaderProgram); } return ret; } // Read texture from buffer BOOL DEMOGFDReadTexture(GX2Texture **ppTexture, u32 index, const void *pData) { GX2Texture *pHeader; u32 ret; u32 headerSize; u32 imageSize; // Check inputs if(pData == NULL || ppTexture == NULL) { return FALSE; } // Check index number of shaders if(index >= GFDGetTextureCount(pData)) { return FALSE; } // Get the size of texture header, image and align headerSize = GFDGetTextureHeaderSize(index, pData); imageSize = GFDGetTextureImageSize(index, pData); if(!headerSize || !imageSize) return FALSE; pHeader = (GX2Texture *)DEMOAllocEx(headerSize, PPC_IO_BUFFER_ALIGN); ret = GFDGetGX2RTexture(pHeader, index, pData); if(!ret) { OSReport("Warning: Invalid Texture :%d", ret); // Free if fail if(pHeader) DEMOFree(pHeader); return ret; } else { // Set the return pointer to the texture header struct *ppTexture = pHeader; } return ret; } // Free vertex shader void DEMOGFDFreeVertexShader(GX2VertexShader *pShader) { if(pShader) { if(pShader->shaderPtr) DEMOGfxFreeMEM2(pShader->shaderPtr); else GX2RDestroyBuffer(&pShader->shaderProgram); DEMOFree(pShader); } } // Free pixel shader void DEMOGFDFreePixelShader(GX2PixelShader *pShader) { if(pShader) { if(pShader->shaderPtr) DEMOGfxFreeMEM2(pShader->shaderPtr); else GX2RDestroyBuffer(&pShader->shaderProgram); DEMOFree(pShader); } } // Free geometry shader void DEMOGFDFreeGeometryShader(GX2GeometryShader *pShader) { if(pShader) { if(pShader->shaderPtr) DEMOGfxFreeMEM2(pShader->shaderPtr); else GX2RDestroyBuffer(&pShader->shaderProgram); if(pShader->copyShaderPtr) DEMOGfxFreeMEM2(pShader->copyShaderPtr); else GX2RDestroyBuffer(&pShader->copyShaderProgram); DEMOFree(pShader); } } // Free compute shader void DEMOGFDFreeComputeShader(GX2ComputeShader *pShader) { if(pShader) { if(pShader->shaderPtr) DEMOGfxFreeMEM2(pShader->shaderPtr); else GX2RDestroyBuffer(&pShader->shaderProgram); DEMOFree(pShader); } } // Free texture void DEMOGFDFreeTexture(GX2Texture *pTexture) { if(pTexture) { GX2RDestroySurface(&pTexture->surface); DEMOFree(pTexture); } } // Read Aligned Texture GX2Texture* DEMOGFDReadAlignedTexture(void **pFileBuf, u32 index, u32 align, const char *fileName) { u32 len; GX2Texture *pTexture; // Read the texture file into a buffer *pFileBuf = DEMOGfxLoadAssetFileAlign(fileName, &len, align); // Check Align mode of the buffer if(GFDGetAlignMode(*pFileBuf) != GFD_ALIGN_MODE_ENABLE) { DEMOGFDFreeAlignedTexture(*pFileBuf); ASSERT(!"Input file isn't aligned. Please use \"-align\" option when it is created by tool."); return NULL; } pTexture = GFDGetGX2RTexturePointer(index, *pFileBuf); return pTexture; } // Free Aligned Texture void DEMOGFDFreeAlignedTexture(void *pFileBuf) { if(pFileBuf) { DEMOFree(pFileBuf); // Destroy the GX2RSurface objects u32 textureCount = GFDGetTextureCount(pFileBuf); for (u32 i=0; isurface); } } }