@@ -32,6 +32,7 @@ internal readonly record struct FrameStamp(long FrameId, long StopwatchTicks)
3232
3333 internal enum DeferredOperationKind
3434 {
35+ TakeScreenshot ,
3536 SaveGame ,
3637 LoadGame
3738 }
@@ -40,6 +41,15 @@ internal readonly struct DeferredOperation
4041 {
4142 public DeferredOperationKind Kind { get ; private init ; }
4243 public uint ? SaveSlot { get ; private init ; }
44+ public GameProcess ? ScreenshotProcess { get ; private init ; }
45+ public PooledTexture ? ScreenshotTexture { get ; private init ; }
46+
47+ public static DeferredOperation TakeScreenshot ( GameProcess process , PooledTexture texture ) => new ( )
48+ {
49+ Kind = DeferredOperationKind . TakeScreenshot ,
50+ ScreenshotTexture = texture ,
51+ ScreenshotProcess = process
52+ } ;
4353
4454 public static DeferredOperation SaveGame ( uint slot ) => new ( )
4555 {
@@ -502,23 +512,19 @@ private void Tick(FrameStamp framestamp, float dt)
502512 bool assetsReady = Content . ResolveAssets ( ) ;
503513 if ( assetsReady )
504514 {
515+ RunDeferredOperations ( ) ;
505516 world . BeginFrame ( ) ;
506517 }
507518
508519 ProcessSounds ( world , dt ) ;
509- RenderFrame ( framestamp , world . RenderItems , dt , assetsReady ) ;
520+ RenderFrame ( world . RenderItems , dt , assetsReady ) ;
510521 HandleInput ( ) ;
511522
512523 if ( assetsReady )
513524 {
514525 ActiveProcess . ProcessWaitOperations ( this ) ;
515526 }
516527
517- if ( assetsReady )
518- {
519- RunDeferredOperations ( ) ;
520- }
521-
522528 RenderContext . EndFrame ( ) ;
523529
524530 try
@@ -532,7 +538,6 @@ private void Tick(FrameStamp framestamp, float dt)
532538 }
533539
534540 private void RenderFrame (
535- in FrameStamp frameStamp ,
536541 SortableEntityGroupView < RenderItem > renderItems ,
537542 float dt ,
538543 bool assetsReady )
@@ -554,8 +559,6 @@ private void RenderFrame(
554559 {
555560 ri . Render ( RenderContext ) ;
556561 }
557-
558- RenderContext . TextureCache . BeginFrame ( frameStamp ) ;
559562 }
560563
561564 private static void ProcessSounds ( World world , float dt )
@@ -622,7 +625,6 @@ private void CreateSysProcess(string mainModule)
622625 //_context.SysProcess?.Dispose();
623626 if ( SysProcess is null )
624627 {
625- //LastScreenshot ??= TakeScreenshot(MainProcess);
626628 MainProcess . VmProcess . Suspend ( ) ;
627629 SysProcess = CreateProcess ( VM , mainModule , _fontSettings ) ;
628630 _clearFramebuffer = false ;
@@ -636,6 +638,11 @@ private void RunDeferredOperations()
636638 {
637639 switch ( op . Kind )
638640 {
641+ case DeferredOperationKind . TakeScreenshot :
642+ Debug . Assert ( op . ScreenshotProcess is not null ) ;
643+ Debug . Assert ( op . ScreenshotTexture . HasValue ) ;
644+ RenderToTexture ( op . ScreenshotProcess , op . ScreenshotTexture . Value . Get ( ) , fence : null ) ;
645+ break ;
639646 case DeferredOperationKind . SaveGame :
640647 Debug . Assert ( op . SaveSlot is not null ) ;
641648 SaveManager . Save ( this , op . SaveSlot . Value ) ;
@@ -653,25 +660,42 @@ private void RunDeferredOperations()
653660 }
654661 }
655662
656- internal PooledTexture RenderToTexture ( GameProcess process )
663+ internal void RenderToTexture ( GameProcess process , Texture texture , Fence ? fence )
657664 {
658- return RenderContext . RenderToTexture ( batch =>
665+ RenderContext . EndFrame ( ) ;
666+
667+ RenderContext . BeginFrame ( _now , RenderContext . OffscreenTarget , clear : true ) ;
668+ ReadOnlySpan < RenderItem > activeItems = process . World . RenderItems . SortActive ( ) ;
669+ foreach ( RenderItem renderItem in activeItems )
659670 {
660- ReadOnlySpan < RenderItem > activeItems = process . World . RenderItems . SortActive ( ) ;
661- foreach ( RenderItem renderItem in activeItems )
662- {
663- renderItem . PerformLayout ( this ) ;
664- }
671+ renderItem . PerformLayout ( this ) ;
672+ }
665673
666- RenderContext . ResolveGlyphs ( ) ;
674+ RenderContext . ResolveGlyphs ( ) ;
667675
668- foreach ( RenderItem renderItem in activeItems )
669- {
670- renderItem . Render ( RenderContext , batch ) ;
671- }
676+ foreach ( RenderItem renderItem in activeItems )
677+ {
678+ renderItem . Render ( RenderContext ) ;
679+ }
680+
681+ RenderContext . EndFrame ( ) ;
682+
683+ CommandList cl = RenderContext . CommandListPool . Rent ( ) ;
684+ cl . Begin ( ) ;
685+ cl . CopyTexture ( source : RenderContext . OffscreenTarget . ColorTarget , texture ) ;
686+ cl . End ( ) ;
687+
688+ if ( fence is not null )
689+ {
690+ RenderContext . GraphicsDevice . SubmitCommands ( cl , fence ) ;
691+ }
692+ else
693+ {
694+ RenderContext . GraphicsDevice . SubmitCommands ( cl ) ;
695+ }
672696
673- RenderContext . TextureCache . BeginFrame ( _now ) ;
674- } ) ;
697+ RenderContext . CommandListPool . Return ( cl ) ;
698+ RenderContext . BeginFrame ( _now , _clearFramebuffer ) ;
675699 }
676700
677701 internal void Defer ( in DeferredOperation operation )
0 commit comments