mirror of
				https://github.com/ryujinx-mirror/ryujinx.git
				synced 2025-11-04 21:12:33 +09:00 
			
		
		
		
	
		
			
				
	
	
		
			151 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			151 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using OpenTK.Graphics.OpenGL;
 | 
						|
using Ryujinx.Graphics.GAL;
 | 
						|
using Ryujinx.Graphics.OpenGL.Image;
 | 
						|
using System;
 | 
						|
using System.Runtime.CompilerServices;
 | 
						|
 | 
						|
namespace Ryujinx.Graphics.OpenGL
 | 
						|
{
 | 
						|
    class Framebuffer : IDisposable
 | 
						|
    {
 | 
						|
        public int Handle { get; private set; }
 | 
						|
 | 
						|
        private FramebufferAttachment _lastDsAttachment;
 | 
						|
 | 
						|
        private readonly TextureView[] _colors;
 | 
						|
 | 
						|
        private int _colorsCount;
 | 
						|
        private bool _dualSourceBlend;
 | 
						|
 | 
						|
        public Framebuffer()
 | 
						|
        {
 | 
						|
            Handle = GL.GenFramebuffer();
 | 
						|
 | 
						|
            _colors = new TextureView[8];
 | 
						|
        }
 | 
						|
 | 
						|
        public int Bind()
 | 
						|
        {
 | 
						|
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, Handle);
 | 
						|
            return Handle;
 | 
						|
        }
 | 
						|
 | 
						|
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 | 
						|
        public void AttachColor(int index, TextureView color)
 | 
						|
        {
 | 
						|
            if (_colors[index] == color)
 | 
						|
            {
 | 
						|
                return;
 | 
						|
            }
 | 
						|
 | 
						|
            FramebufferAttachment attachment = FramebufferAttachment.ColorAttachment0 + index;
 | 
						|
 | 
						|
            GL.FramebufferTexture(FramebufferTarget.Framebuffer, attachment, color?.Handle ?? 0, 0);
 | 
						|
 | 
						|
            _colors[index] = color;
 | 
						|
        }
 | 
						|
 | 
						|
        public void AttachDepthStencil(TextureView depthStencil)
 | 
						|
        {
 | 
						|
            // Detach the last depth/stencil buffer if there is any.
 | 
						|
            if (_lastDsAttachment != 0)
 | 
						|
            {
 | 
						|
                GL.FramebufferTexture(FramebufferTarget.Framebuffer, _lastDsAttachment, 0, 0);
 | 
						|
            }
 | 
						|
 | 
						|
            if (depthStencil != null)
 | 
						|
            {
 | 
						|
                FramebufferAttachment attachment;
 | 
						|
 | 
						|
                if (IsPackedDepthStencilFormat(depthStencil.Format))
 | 
						|
                {
 | 
						|
                    attachment = FramebufferAttachment.DepthStencilAttachment;
 | 
						|
                }
 | 
						|
                else if (IsDepthOnlyFormat(depthStencil.Format))
 | 
						|
                {
 | 
						|
                    attachment = FramebufferAttachment.DepthAttachment;
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    attachment = FramebufferAttachment.StencilAttachment;
 | 
						|
                }
 | 
						|
 | 
						|
                GL.FramebufferTexture(
 | 
						|
                    FramebufferTarget.Framebuffer,
 | 
						|
                    attachment,
 | 
						|
                    depthStencil.Handle,
 | 
						|
                    0);
 | 
						|
 | 
						|
                _lastDsAttachment = attachment;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                _lastDsAttachment = 0;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        public void SetDualSourceBlend(bool enable)
 | 
						|
        {
 | 
						|
            bool oldEnable = _dualSourceBlend;
 | 
						|
 | 
						|
            _dualSourceBlend = enable;
 | 
						|
 | 
						|
            // When dual source blend is used,
 | 
						|
            // we can only have one draw buffer.
 | 
						|
            if (enable)
 | 
						|
            {
 | 
						|
                GL.DrawBuffer(DrawBufferMode.ColorAttachment0);
 | 
						|
            }
 | 
						|
            else if (oldEnable)
 | 
						|
            {
 | 
						|
                SetDrawBuffersImpl(_colorsCount);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        public void SetDrawBuffers(int colorsCount)
 | 
						|
        {
 | 
						|
            if (_colorsCount != colorsCount && !_dualSourceBlend)
 | 
						|
            {
 | 
						|
                SetDrawBuffersImpl(colorsCount);
 | 
						|
            }
 | 
						|
 | 
						|
            _colorsCount = colorsCount;
 | 
						|
        }
 | 
						|
 | 
						|
        private void SetDrawBuffersImpl(int colorsCount)
 | 
						|
        {
 | 
						|
            DrawBuffersEnum[] drawBuffers = new DrawBuffersEnum[colorsCount];
 | 
						|
 | 
						|
            for (int index = 0; index < colorsCount; index++)
 | 
						|
            {
 | 
						|
                drawBuffers[index] = DrawBuffersEnum.ColorAttachment0 + index;
 | 
						|
            }
 | 
						|
 | 
						|
            GL.DrawBuffers(colorsCount, drawBuffers);
 | 
						|
        }
 | 
						|
 | 
						|
        private static bool IsPackedDepthStencilFormat(Format format)
 | 
						|
        {
 | 
						|
            return format == Format.D24UnormS8Uint ||
 | 
						|
                   format == Format.D32FloatS8Uint;
 | 
						|
        }
 | 
						|
 | 
						|
        private static bool IsDepthOnlyFormat(Format format)
 | 
						|
        {
 | 
						|
            return format == Format.D16Unorm ||
 | 
						|
                   format == Format.D24X8Unorm ||
 | 
						|
                   format == Format.D32Float;
 | 
						|
        }
 | 
						|
 | 
						|
        public void Dispose()
 | 
						|
        {
 | 
						|
            if (Handle != 0)
 | 
						|
            {
 | 
						|
                GL.DeleteFramebuffer(Handle);
 | 
						|
 | 
						|
                Handle = 0;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |