 484eb645ae
			
		
	
	
		484eb645ae
		
			
		
	
	
	
	
		
			
			* Initial implementation of Render Target Scaling Works with most games I have. No GUI option right now, it is hardcoded. Missing handling for texelFetch operation. * Realtime Configuration, refactoring. * texelFetch scaling on fragment shader (WIP) * Improve Shader-Side changes. * Fix potential crash when no color/depth bound * Workaround random uses of textures in compute. This was blacklisting textures in a few games despite causing no bugs. Will eventually add full support so this doesn't break anything. * Fix scales oscillating when changing between non-native scales. * Scaled textures on compute, cleanup, lazier uniform update. * Cleanup. * Fix stupidity * Address Thog Feedback. * Cover most of GDK's feedback (two comments remain) * Fix bad rename * Move IsDepthStencil to FormatExtensions, add docs. * Fix default config, square texture detection. * Three final fixes: - Nearest copy when texture is integer format. - Texture2D -> Texture3D copy correctly blacklists the texture before trying an unscaled copy (caused driver error) - Discount small textures. * Remove scale threshold. Not needed right now - we'll see if we run into problems. * All CPU modification blacklists scale. * Fix comment.
		
			
				
	
	
		
			161 lines
		
	
	
		
			No EOL
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			161 lines
		
	
	
		
			No EOL
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using Ryujinx.Graphics.GAL;
 | |
| using Ryujinx.Graphics.Gpu.Image;
 | |
| using System;
 | |
| using System.Collections.Concurrent;
 | |
| 
 | |
| namespace Ryujinx.Graphics.Gpu
 | |
| {
 | |
|     using Texture = Image.Texture;
 | |
| 
 | |
|     /// <summary>
 | |
|     /// GPU image presentation window.
 | |
|     /// </summary>
 | |
|     public class Window
 | |
|     {
 | |
|         private readonly GpuContext _context;
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Texture presented on the window.
 | |
|         /// </summary>
 | |
|         private struct PresentationTexture
 | |
|         {
 | |
|             /// <summary>
 | |
|             /// Texture information.
 | |
|             /// </summary>
 | |
|             public TextureInfo Info { get; }
 | |
| 
 | |
|             /// <summary>
 | |
|             /// Texture crop region.
 | |
|             /// </summary>
 | |
|             public ImageCrop Crop { get; }
 | |
| 
 | |
|             /// <summary>
 | |
|             /// Texture acquire callback.
 | |
|             /// </summary>
 | |
|             public Action<GpuContext, object> AcquireCallback { get; }
 | |
| 
 | |
|             /// <summary>
 | |
|             /// Texture release callback.
 | |
|             /// </summary>
 | |
|             public Action<object> ReleaseCallback { get; }
 | |
| 
 | |
|             /// <summary>
 | |
|             /// User defined object, passed to the various callbacks.
 | |
|             /// </summary>
 | |
|             public object UserObj { get; }
 | |
| 
 | |
|             /// <summary>
 | |
|             /// Creates a new instance of the presentation texture.
 | |
|             /// </summary>
 | |
|             /// <param name="info">Information of the texture to be presented</param>
 | |
|             /// <param name="crop">Texture crop region</param>
 | |
|             /// <param name="acquireCallback">Texture acquire callback</param>
 | |
|             /// <param name="releaseCallback">Texture release callback</param>
 | |
|             /// <param name="userObj">User defined object passed to the release callback, can be used to identify the texture</param>
 | |
|             public PresentationTexture(
 | |
|                 TextureInfo                info,
 | |
|                 ImageCrop                  crop,
 | |
|                 Action<GpuContext, object> acquireCallback,
 | |
|                 Action<object>             releaseCallback,
 | |
|                 object                     userObj)
 | |
|             {
 | |
|                 Info            = info;
 | |
|                 Crop            = crop;
 | |
|                 AcquireCallback = acquireCallback;
 | |
|                 ReleaseCallback = releaseCallback;
 | |
|                 UserObj         = userObj;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private readonly ConcurrentQueue<PresentationTexture> _frameQueue;
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Creates a new instance of the GPU presentation window.
 | |
|         /// </summary>
 | |
|         /// <param name="context">GPU emulation context</param>
 | |
|         public Window(GpuContext context)
 | |
|         {
 | |
|             _context = context;
 | |
| 
 | |
|             _frameQueue = new ConcurrentQueue<PresentationTexture>();
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Enqueues a frame for presentation.
 | |
|         /// This method is thread safe and can be called from any thread.
 | |
|         /// When the texture is presented and not needed anymore, the release callback is called.
 | |
|         /// It's an error to modify the texture after calling this method, before the release callback is called.
 | |
|         /// </summary>
 | |
|         /// <param name="address">CPU virtual address of the texture data</param>
 | |
|         /// <param name="width">Texture width</param>
 | |
|         /// <param name="height">Texture height</param>
 | |
|         /// <param name="stride">Texture stride for linear texture, should be zero otherwise</param>
 | |
|         /// <param name="isLinear">Indicates if the texture is linear, normally false</param>
 | |
|         /// <param name="gobBlocksInY">GOB blocks in the Y direction, for block linear textures</param>
 | |
|         /// <param name="format">Texture format</param>
 | |
|         /// <param name="bytesPerPixel">Texture format bytes per pixel (must match the format)</param>
 | |
|         /// <param name="crop">Texture crop region</param>
 | |
|         /// <param name="acquireCallback">Texture acquire callback</param>
 | |
|         /// <param name="releaseCallback">Texture release callback</param>
 | |
|         /// <param name="userObj">User defined object passed to the release callback</param>
 | |
|         public void EnqueueFrameThreadSafe(
 | |
|             ulong                      address,
 | |
|             int                        width,
 | |
|             int                        height,
 | |
|             int                        stride,
 | |
|             bool                       isLinear,
 | |
|             int                        gobBlocksInY,
 | |
|             Format                     format,
 | |
|             int                        bytesPerPixel,
 | |
|             ImageCrop                  crop,
 | |
|             Action<GpuContext, object> acquireCallback,
 | |
|             Action<object>             releaseCallback,
 | |
|             object                     userObj)
 | |
|         {
 | |
|             FormatInfo formatInfo = new FormatInfo(format, 1, 1, bytesPerPixel);
 | |
| 
 | |
|             TextureInfo info = new TextureInfo(
 | |
|                 address,
 | |
|                 width,
 | |
|                 height,
 | |
|                 1,
 | |
|                 1,
 | |
|                 1,
 | |
|                 1,
 | |
|                 stride,
 | |
|                 isLinear,
 | |
|                 gobBlocksInY,
 | |
|                 1,
 | |
|                 1,
 | |
|                 Target.Texture2D,
 | |
|                 formatInfo);
 | |
| 
 | |
|             _frameQueue.Enqueue(new PresentationTexture(info, crop, acquireCallback, releaseCallback, userObj));
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Presents a texture on the queue.
 | |
|         /// If the queue is empty, then no texture is presented.
 | |
|         /// </summary>
 | |
|         /// <param name="swapBuffersCallback">Callback method to call when a new texture should be presented on the screen</param>
 | |
|         public void Present(Action swapBuffersCallback)
 | |
|         {
 | |
|             _context.AdvanceSequence();
 | |
| 
 | |
|             if (_frameQueue.TryDequeue(out PresentationTexture pt))
 | |
|             {
 | |
|                 pt.AcquireCallback(_context, pt.UserObj);
 | |
| 
 | |
|                 Texture texture = _context.Methods.TextureManager.FindOrCreateTexture(pt.Info, TextureSearchFlags.WithUpscale);
 | |
| 
 | |
|                 texture.SynchronizeMemory();
 | |
| 
 | |
|                 _context.Renderer.Window.Present(texture.HostTexture, pt.Crop);
 | |
| 
 | |
|                 swapBuffersCallback();
 | |
| 
 | |
|                 pt.ReleaseCallback(pt.UserObj);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| } |