@ -23,16 +23,21 @@ static IUnityGraphicsPS5* s_GraphicsPS5 = nullptr; // Old Gnmp-based gr
static IUnityGraphicsAgcPS5 * s_GraphicsAgcPS5 = nullptr ; // New Agc-based graphics API (NGGC)
static IUnityGraphicsAgcPS5 * s_GraphicsAgcPS5 = nullptr ; // New Agc-based graphics API (NGGC)
static UnityGfxRenderer s_RendererType = kUnityGfxRendererNull ;
static UnityGfxRenderer s_RendererType = kUnityGfxRendererNull ;
MfsrPhysicalMemoryBlock * s_mfsrSharedResourcesMemoryBlocks = nullptr ;
MfsrSharedResources s_mfsrSharedResources = nullptr ;
static bool s_mfsrInitialized = false ;
static MfsrPhysicalMemoryBlock * s_mfsrSharedResourcesMemoryBlocks = nullptr ;
static MfsrSharedResources s_mfsrSharedResources = nullptr ;
// Just use a single context for now to keep things simple
// "Multiple contexts (up to 4) can be generated to perform multiple MFSR processes within an application."
// "Multiple contexts (up to 4) can be generated to perform multiple MFSR processes within an application."
static bool s_mfsrInitialized = false ;
static Core : : BasicContext s_AgcContext ;
static MfsrPhysicalMemoryBlock * s_mfsrMemoryBlocks = nullptr ;
static MfsrContext s_mfsrContext = nullptr ;
static Core : : Texture s_outputColorTexture ;
static const int MaxNumContexts = 4 ;
struct PssrContext
{
Core : : BasicContext agcContext ;
MfsrPhysicalMemoryBlock * mfsrMemoryBlocks = nullptr ;
MfsrContext mfsrContext = nullptr ;
Core : : Texture outputColorTexture ;
} ;
static PssrContext s_contexts [ MaxNumContexts ] ;
static void UNITY_INTERFACE_API OnGraphicsDeviceEvent ( UnityGfxDeviceEventType eventType ) ;
static void UNITY_INTERFACE_API OnGraphicsDeviceEvent ( UnityGfxDeviceEventType eventType ) ;
static void UNITY_INTERFACE_API OnRenderEventAndData ( int eventID , void * data ) ;
static void UNITY_INTERFACE_API OnRenderEventAndData ( int eventID , void * data ) ;
@ -200,6 +205,8 @@ extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API ReleasePssr()
typedef struct pssr_init_params_s
typedef struct pssr_init_params_s
{
{
uint32_t contextIndex ;
uint32_t displayWidth ;
uint32_t displayWidth ;
uint32_t displayHeight ;
uint32_t displayHeight ;
uint32_t maxRenderWidth ;
uint32_t maxRenderWidth ;
@ -210,6 +217,8 @@ typedef struct pssr_init_params_s
typedef struct pssr_dispatch_params_s
typedef struct pssr_dispatch_params_s
{
{
uint32_t contextIndex ;
sce : : Agc : : Core : : Texture * color ;
sce : : Agc : : Core : : Texture * color ;
sce : : Agc : : Core : : Texture * depth ;
sce : : Agc : : Core : : Texture * depth ;
sce : : Agc : : Core : : Texture * prevDepth ;
sce : : Agc : : Core : : Texture * prevDepth ;
@ -240,6 +249,16 @@ typedef struct pssr_dispatch_params_s
extern " C " int32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API CreatePssrContext ( const pssr_init_params_t * params , Core : : Texture * * outputColorTexture )
extern " C " int32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API CreatePssrContext ( const pssr_init_params_t * params , Core : : Texture * * outputColorTexture )
{
{
if ( params - > contextIndex < 0 | | params - > contextIndex > = MaxNumContexts )
{
std : : stringstream msg ;
msg < < " Invalid PSSR context index: " < < params - > contextIndex ;
UNITY_LOG_ERROR ( s_Log , msg . str ( ) . c_str ( ) ) ;
return - 1 ;
}
PssrContext & context = s_contexts [ params - > contextIndex ] ;
MfsrContextInitParameters initParams = { } ;
MfsrContextInitParameters initParams = { } ;
initParams . init ( ) ;
initParams . init ( ) ;
initParams . m_outputColorWidth = params - > displayWidth ;
initParams . m_outputColorWidth = params - > displayWidth ;
@ -268,7 +287,7 @@ extern "C" int32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API CreatePssrContext(
MfsrContextInitRequirement mfsrInitRequirement = { } ;
MfsrContextInitRequirement mfsrInitRequirement = { } ;
getMfsrContextInitRequirement ( & mfsrInitRequirement , & initParams ) ;
getMfsrContextInitRequirement ( & mfsrInitRequirement , & initParams ) ;
s_ mfsrMemoryBlocks = new MfsrPhysicalMemoryBlock [ mfsrInitRequirement . m_physicalMemoryBlockCount ] ;
context . mfsrMemoryBlocks = new MfsrPhysicalMemoryBlock [ mfsrInitRequirement . m_physicalMemoryBlockCount ] ;
size_t size = mfsrInitRequirement . m_physicalMemoryBlockSize ;
size_t size = mfsrInitRequirement . m_physicalMemoryBlockSize ;
size_t align = mfsrInitRequirement . m_physicalMemoryBlockAlignment ;
size_t align = mfsrInitRequirement . m_physicalMemoryBlockAlignment ;
@ -279,12 +298,12 @@ extern "C" int32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API CreatePssrContext(
for ( uint32_t i = 0 ; i < mfsrInitRequirement . m_physicalMemoryBlockCount ; i + + )
for ( uint32_t i = 0 ; i < mfsrInitRequirement . m_physicalMemoryBlockCount ; i + + )
{
{
s_ mfsrMemoryBlocks[ i ] . m_size = size ;
s_ mfsrMemoryBlocks[ i ] . m_offset = m_mfsrMemoryPhysicalAddress + mfsrInitRequirement . m_physicalMemoryBlockSize * i ;
context . mfsrMemoryBlocks [ i ] . m_size = size ;
context . mfsrMemoryBlocks [ i ] . m_offset = m_mfsrMemoryPhysicalAddress + mfsrInitRequirement . m_physicalMemoryBlockSize * i ;
}
}
initParams . m_sharedResources = s_mfsrSharedResources ;
initParams . m_sharedResources = s_mfsrSharedResources ;
initParams . m_physicalMemoryBlocks = s_ mfsrMemoryBlocks;
initParams . m_physicalMemoryBlocks = context . mfsrMemoryBlocks ;
initParams . m_physicalMemoryBlockCount = mfsrInitRequirement . m_physicalMemoryBlockCount ;
initParams . m_physicalMemoryBlockCount = mfsrInitRequirement . m_physicalMemoryBlockCount ;
}
}
@ -309,7 +328,7 @@ extern "C" int32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API CreatePssrContext(
texSpec . m_dataAddress = s_GraphicsAgcPS5 - > AllocateGPUMemory ( sizeAlign . m_size , MfsrAlignment : : kOutputTexture ) ;
texSpec . m_dataAddress = s_GraphicsAgcPS5 - > AllocateGPUMemory ( sizeAlign . m_size , MfsrAlignment : : kOutputTexture ) ;
}
}
int res = Core : : initialize ( & s_ outputColorTexture, & texSpec ) ;
int res = Core : : initialize ( & context . outputColorTexture , & texSpec ) ;
if ( res ! = SCE_OK )
if ( res ! = SCE_OK )
{
{
std : : stringstream msg ;
std : : stringstream msg ;
@ -318,20 +337,20 @@ extern "C" int32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API CreatePssrContext(
return res ;
return res ;
}
}
* outputColorTexture = & s_ outputColorTexture;
* outputColorTexture = & context . outputColorTexture ;
}
}
// Set up command buffer for NGGC
// Set up command buffer for NGGC
if ( s_RendererType = = kUnityGfxRendererPS5NGGC & & s_GraphicsAgcPS5 ! = nullptr )
if ( s_RendererType = = kUnityGfxRendererPS5NGGC & & s_GraphicsAgcPS5 ! = nullptr )
{
{
const size_t agcContextSize = 128 * 1024 ;
const size_t agcContextSize = 128 * 1024 ;
s_A gcContext. m_dcb . init ( s_GraphicsAgcPS5 - > AllocateGPUMemory ( agcContextSize , Alignment : : kCommandBuffer ) , agcContextSize ) ;
s_A gcContext. m_bdr . init ( & s_A gcContext. m_dcb , & s_A gcContext. m_dcb ) ;
s_A gcContext. m_sb . init ( 256 , & s_A gcContext. m_dcb , & s_A gcContext. m_dcb ) ;
context . a gcContext. m_dcb . init ( s_GraphicsAgcPS5 - > AllocateGPUMemory ( agcContextSize , Alignment : : kCommandBuffer ) , agcContextSize ) ;
context . a gcContext. m_bdr . init ( & context . a gcContext. m_dcb , & context . a gcContext. m_dcb ) ;
context . a gcContext. m_sb . init ( 256 , & context . a gcContext. m_dcb , & context . a gcContext. m_dcb ) ;
}
}
// Finally, create the actual MFSR context
// Finally, create the actual MFSR context
int res = createMfsrContext ( & s_ mfsrContext, & initParams ) ;
int res = createMfsrContext ( & context . mfsrContext , & initParams ) ;
if ( res ! = SCE_OK )
if ( res ! = SCE_OK )
{
{
std : : stringstream msg ;
std : : stringstream msg ;
@ -344,8 +363,18 @@ extern "C" int32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API CreatePssrContext(
return SCE_OK ;
return SCE_OK ;
}
}
extern " C " void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API DestroyPssrContext ( )
extern " C " void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API DestroyPssrContext ( uint32_t contextIndex )
{
{
if ( contextIndex < 0 | | contextIndex > = MaxNumContexts )
{
std : : stringstream msg ;
msg < < " Invalid PSSR context index: " < < contextIndex ;
UNITY_LOG_ERROR ( s_Log , msg . str ( ) . c_str ( ) ) ;
return ;
}
PssrContext & context = s_contexts [ contextIndex ] ;
// TODO: this still crashes often due to race conditions between dispatch above and release here
// TODO: this still crashes often due to race conditions between dispatch above and release here
// The main cause will be that the MFSR context is released before the already dispatched commands are executed on the GPU
// The main cause will be that the MFSR context is released before the already dispatched commands are executed on the GPU
// Just adding mutexes everywhere is not going to fix that
// Just adding mutexes everywhere is not going to fix that
@ -353,36 +382,36 @@ extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API DestroyPssrContext()
//
//
// Another issue is that we reuse the same static s_mfsrContext pointer when recreating the MFSR context, which can lead to situations where dispatch uses the wrong context object
// Another issue is that we reuse the same static s_mfsrContext pointer when recreating the MFSR context, which can lead to situations where dispatch uses the wrong context object
// Multi-buffering those pointers will help with that
// Multi-buffering those pointers will help with that
if ( s_ mfsrContext ! = nullptr )
if ( context . mfsrContext ! = nullptr )
{
{
releaseMfsrContext ( s_ mfsrContext) ;
s_ mfsrContext = nullptr ;
releaseMfsrContext ( context . mfsrContext ) ;
context . mfsrContext = nullptr ;
}
}
if ( s_GraphicsAgcPS5 ! = nullptr & & s_A gcContext. m_dcb . m_bottom ! = nullptr )
if ( s_GraphicsAgcPS5 ! = nullptr & & context . a gcContext. m_dcb . m_bottom ! = nullptr )
{
{
s_GraphicsAgcPS5 - > ReleaseGPUMemory ( s_A gcContext. m_dcb . m_bottom ) ;
s_A gcContext. m_dcb . clear ( ) ;
s_GraphicsAgcPS5 - > ReleaseGPUMemory ( context . a gcContext. m_dcb . m_bottom ) ;
context . a gcContext. m_dcb . clear ( ) ;
}
}
if ( s_ outputColorTexture. getDataAddress ( ) )
if ( context . outputColorTexture . getDataAddress ( ) )
{
{
if ( s_GraphicsPS5 ! = nullptr )
if ( s_GraphicsPS5 ! = nullptr )
{
{
s_GraphicsPS5 - > ReleaseGPUMemory ( s_ outputColorTexture. getDataAddress ( ) ) ;
s_GraphicsPS5 - > ReleaseGPUMemory ( context . outputColorTexture . getDataAddress ( ) ) ;
}
}
else if ( s_GraphicsAgcPS5 ! = nullptr )
else if ( s_GraphicsAgcPS5 ! = nullptr )
{
{
s_GraphicsAgcPS5 - > ReleaseGPUMemory ( s_ outputColorTexture. getDataAddress ( ) ) ;
s_GraphicsAgcPS5 - > ReleaseGPUMemory ( context . outputColorTexture . getDataAddress ( ) ) ;
}
}
s_ outputColorTexture. init ( ) ;
context . outputColorTexture . init ( ) ;
}
}
if ( s_ mfsrMemoryBlocks ! = nullptr )
if ( context . mfsrMemoryBlocks ! = nullptr )
{
{
delete [ ] s_ mfsrMemoryBlocks;
s_ mfsrMemoryBlocks = nullptr ;
delete [ ] context . mfsrMemoryBlocks ;
context . mfsrMemoryBlocks = nullptr ;
}
}
UNITY_LOG ( s_Log , " Destroyed PSSR context " ) ;
UNITY_LOG ( s_Log , " Destroyed PSSR context " ) ;
@ -411,10 +440,18 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data)
}
}
case 1 : // Execute PSSR
case 1 : // Execute PSSR
{
{
if ( s_mfsrContext = = nullptr )
auto * params = ( pssr_dispatch_params_t * ) data ;
if ( params - > contextIndex < 0 | | params - > contextIndex > = MaxNumContexts )
{
std : : stringstream msg ;
msg < < " Invalid PSSR context index: " < < params - > contextIndex ;
UNITY_LOG_ERROR ( s_Log , msg . str ( ) . c_str ( ) ) ;
break ;
break ;
}
auto * params = ( pssr_dispatch_params_t * ) data ;
PssrContext & context = s_contexts [ params - > contextIndex ] ;
if ( context . mfsrContext = = nullptr )
break ;
// How we obtain a command buffer to dispatch to depends on which graphics API we're using in Unity
// How we obtain a command buffer to dispatch to depends on which graphics API we're using in Unity
sce : : Agc : : DrawCommandBuffer * cmd = nullptr ;
sce : : Agc : : DrawCommandBuffer * cmd = nullptr ;
@ -425,7 +462,7 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data)
}
}
else if ( s_RendererType = = kUnityGfxRendererPS5NGGC )
else if ( s_RendererType = = kUnityGfxRendererPS5NGGC )
{
{
Core : : BasicContext & ctx = s_A gcContext. reset ( ) ;
Core : : BasicContext & ctx = context . a gcContext. reset ( ) ;
cmd = & ctx . m_dcb ;
cmd = & ctx . m_dcb ;
}
}
@ -457,7 +494,7 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data)
dispatchParams . m_reset = params - > resetHistory ! = 0 ;
dispatchParams . m_reset = params - > resetHistory ! = 0 ;
dispatchParams . m_flags = params - > flags ;
dispatchParams . m_flags = params - > flags ;
dispatchMfsr ( s_ mfsrContext, cmd , & dispatchParams ) ;
dispatchMfsr ( context . mfsrContext , cmd , & dispatchParams ) ;
cmd - > popMarker ( ) ;
cmd - > popMarker ( ) ;
@ -469,7 +506,8 @@ static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data)
}
}
case 2 : // Destroy PSSR context
case 2 : // Destroy PSSR context
{
{
DestroyPssrContext ( ) ;
uint32_t * contextIndex = ( uint32_t * ) data ;
DestroyPssrContext ( * contextIndex ) ;
break ;
break ;
}
}
}
}