simplify IGL 3: Remove ability to make custom blend states (was never used), only have 2 functions for blending, one enabling "normal" blending, one disabling blending (with alpha copy semantics) (only 2 which actually were used)

This commit is contained in:
CasualPokePlayer 2023-08-22 16:44:45 -07:00
parent 757ae3293f
commit 8c1d996b80
16 changed files with 63 additions and 332 deletions

View File

@ -116,33 +116,14 @@ namespace BizHawk.Bizware.BizwareGL
VertexLayout CreateVertexLayout();
/// <summary>
/// Creates a blending state object
/// Enables normal (non-premultiplied) alpha blending.
/// </summary>
IBlendState CreateBlendState(BlendingFactorSrc colorSource, BlendEquationMode colorEquation, BlendingFactorDest colorDest,
BlendingFactorSrc alphaSource, BlendEquationMode alphaEquation, BlendingFactorDest alphaDest);
void EnableBlending();
/// <summary>
/// retrieves a blend state for opaque rendering
/// Alpha values are copied from the source fragment.
/// Disables blending (alpha values are copied from the source fragment)
/// </summary>
IBlendState BlendNoneCopy { get; }
/// <summary>
/// retrieves a blend state for opaque rendering
/// Alpha values are written as opaque
/// </summary>
IBlendState BlendNoneOpaque { get; }
/// <summary>
/// retrieves a blend state for normal (non-premultiplied) alpha blending.
/// Alpha values are copied from the source fragment.
/// </summary>
IBlendState BlendNormal { get; }
/// <summary>
/// Sets the current blending state object
/// </summary>
void SetBlendState(IBlendState rsBlend);
void DisableBlending();
/// <summary>
/// Creates a texture with the specified dimensions

View File

@ -84,7 +84,9 @@ namespace BizHawk.Bizware.BizwareGL
void RectFill(float x, float y, float w, float h);
void SetBlendState(IBlendState rsBlend);
void EnableBlending();
void DisableBlending();
/// <summary>
/// Sets the specified corner color (for the gradient effect)

View File

@ -125,7 +125,7 @@ namespace BizHawk.Bizware.BizwareGL
pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; //useless color
pData[i++] = 1; pData[i] = v1;
Owner.SetBlendState(Owner.BlendNoneCopy);
Owner.DisableBlending();
Owner.Draw(new(pData), 4);
}

View File

@ -1,11 +0,0 @@
namespace BizHawk.Bizware.BizwareGL
{
public enum BlendEquationMode
{
FuncAdd = 0x8006,
Min = 0x8007,
Max = 0x8008,
FuncSubtract = 0x800A,
FuncReverseSubtract = 0x800B,
}
}

View File

@ -1,25 +0,0 @@
namespace BizHawk.Bizware.BizwareGL
{
public enum BlendingFactorDest
{
Zero = 0x0000,
One = 0x0001,
SrcColor = 0x0300,
OneMinusSrcColor = 0x0301,
SrcAlpha = 0x0302,
OneMinusSrcAlpha = 0x0303,
DstAlpha = 0x0304,
OneMinusDstAlpha = 0x0305,
DstColor = 0x0306,
OneMinusDstColor = 0x0307,
SrcAlphaSaturate = 0x0308,
ConstantColor = 0x8001,
OneMinusConstantColor = 0x8002,
ConstantAlpha = 0x8003,
OneMinusConstantAlpha = 0x8004,
Src1Alpha = 0x8589,
Src1Color = 0x88F9,
OneMinusSrc1Color = 0x88FA,
OneMinusSrc1Alpha = 0x88FB,
}
}

View File

@ -1,25 +0,0 @@
namespace BizHawk.Bizware.BizwareGL
{
public enum BlendingFactorSrc
{
Zero = 0x0000,
One = 0x0001,
SrcColor = 0x0300,
OneMinusSrcColor = 0x0301,
SrcAlpha = 0x0302,
OneMinusSrcAlpha = 0x0303,
DstAlpha = 0x0304,
OneMinusDstAlpha = 0x0305,
DstColor = 0x0306,
OneMinusDstColor = 0x0307,
SrcAlphaSaturate = 0x0308,
ConstantColor = 0x8001,
OneMinusConstantColor = 0x8002,
ConstantAlpha = 0x8003,
OneMinusConstantAlpha = 0x8004,
Src1Alpha = 0x8589,
Src1Color = 0x88F9,
OneMinusSrc1Color = 0x88FA,
OneMinusSrc1Alpha = 0x88FB,
}
}

View File

@ -38,7 +38,6 @@ namespace BizHawk.Bizware.Graphics
private Pipeline _currPipeline;
// misc state
private CacheBlendState _rsBlendNoneVerbatim, _rsBlendNoneOpaque, _rsBlendNormal;
private readonly HashSet<RenderTarget> _renderTargets = new();
public string API => "D3D9";
@ -77,7 +76,6 @@ namespace BizHawk.Bizware.Graphics
OffscreenNativeWindow = wminfo.info.win.window;
CreateDevice();
CreateRenderStates();
}
public void AlternateVsyncPass(int pass)
@ -213,15 +211,6 @@ namespace BizHawk.Bizware.Graphics
public void ClearColor(Color color)
=> _device.Clear(ClearFlags.Target, color.ToSharpDXColor(), 0.0f, 0);
public IBlendState CreateBlendState(
BlendingFactorSrc colorSource,
BlendEquationMode colorEquation,
BlendingFactorDest colorDest,
BlendingFactorSrc alphaSource,
BlendEquationMode alphaEquation,
BlendingFactorDest alphaDest)
=> new CacheBlendState(true, colorSource, colorEquation, colorDest, alphaSource, alphaEquation, alphaDest);
public void FreeTexture(Texture2d tex)
{
var tw = (TextureWrapper)tex.Opaque;
@ -301,94 +290,22 @@ namespace BizHawk.Bizware.Graphics
}
}
private static BlendOperation ConvertBlendOp(BlendEquationMode glMode)
=> glMode switch
{
BlendEquationMode.FuncAdd => BlendOperation.Add,
BlendEquationMode.FuncSubtract => BlendOperation.Subtract,
BlendEquationMode.Max => BlendOperation.Maximum,
BlendEquationMode.Min => BlendOperation.Minimum,
BlendEquationMode.FuncReverseSubtract => BlendOperation.ReverseSubtract,
_ => throw new InvalidOperationException()
};
private static Blend ConvertBlendArg(BlendingFactorDest glMode)
=> ConvertBlendArg((BlendingFactorSrc)glMode);
private static Blend ConvertBlendArg(BlendingFactorSrc glMode)
=> glMode switch
{
BlendingFactorSrc.Zero => Blend.Zero,
BlendingFactorSrc.One => Blend.One,
BlendingFactorSrc.SrcColor => Blend.SourceColor,
BlendingFactorSrc.OneMinusSrcColor => Blend.InverseSourceColor,
BlendingFactorSrc.SrcAlpha => Blend.SourceAlpha,
BlendingFactorSrc.OneMinusSrcAlpha => Blend.InverseSourceAlpha,
BlendingFactorSrc.DstAlpha => Blend.DestinationAlpha,
BlendingFactorSrc.OneMinusDstAlpha => Blend.InverseDestinationAlpha,
BlendingFactorSrc.DstColor => Blend.DestinationColor,
BlendingFactorSrc.OneMinusDstColor => Blend.InverseDestinationColor,
BlendingFactorSrc.SrcAlphaSaturate => Blend.SourceAlphaSaturated,
BlendingFactorSrc.ConstantColor => Blend.BlendFactor,
BlendingFactorSrc.OneMinusConstantColor => Blend.InverseBlendFactor,
BlendingFactorSrc.ConstantAlpha => throw new NotSupportedException(),
BlendingFactorSrc.OneMinusConstantAlpha => throw new NotSupportedException(),
BlendingFactorSrc.Src1Alpha => throw new NotSupportedException(),
BlendingFactorSrc.Src1Color => throw new NotSupportedException(),
BlendingFactorSrc.OneMinusSrc1Color => throw new NotSupportedException(),
BlendingFactorSrc.OneMinusSrc1Alpha => throw new NotSupportedException(),
_ => throw new InvalidOperationException()
};
public void SetBlendState(IBlendState rsBlend)
{
var myBs = (CacheBlendState)rsBlend;
if (myBs.Enabled)
public void EnableBlending()
{
_device.SetRenderState(RenderState.AlphaBlendEnable, true);
_device.SetRenderState(RenderState.SeparateAlphaBlendEnable, true);
_device.SetRenderState(RenderState.BlendOperation, ConvertBlendOp(myBs.colorEquation));
_device.SetRenderState(RenderState.SourceBlend, ConvertBlendArg(myBs.colorSource));
_device.SetRenderState(RenderState.DestinationBlend, ConvertBlendArg(myBs.colorDest));
_device.SetRenderState(RenderState.BlendOperation, BlendOperation.Add);
_device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);
_device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha);
_device.SetRenderState(RenderState.BlendOperationAlpha, ConvertBlendOp(myBs.alphaEquation));
_device.SetRenderState(RenderState.SourceBlendAlpha, ConvertBlendArg(myBs.alphaSource));
_device.SetRenderState(RenderState.DestinationBlendAlpha, ConvertBlendArg(myBs.alphaDest));
}
else
{
_device.SetRenderState(RenderState.AlphaBlendEnable, false);
_device.SetRenderState(RenderState.BlendOperationAlpha, BlendOperation.Add);
_device.SetRenderState(RenderState.SourceBlendAlpha, Blend.One);
_device.SetRenderState(RenderState.DestinationBlendAlpha, Blend.Zero);
}
if (rsBlend == _rsBlendNoneOpaque)
{
// make sure constant color is set correctly
_device.SetRenderState(RenderState.BlendFactor, -1); // white
}
}
private void CreateRenderStates()
{
_rsBlendNoneVerbatim = new(
false,
BlendingFactorSrc.One, BlendEquationMode.FuncAdd, BlendingFactorDest.Zero,
BlendingFactorSrc.One, BlendEquationMode.FuncAdd, BlendingFactorDest.Zero);
_rsBlendNoneOpaque = new(
false,
BlendingFactorSrc.One, BlendEquationMode.FuncAdd, BlendingFactorDest.Zero,
BlendingFactorSrc.ConstantAlpha, BlendEquationMode.FuncAdd, BlendingFactorDest.Zero);
_rsBlendNormal = new(
true,
BlendingFactorSrc.SrcAlpha, BlendEquationMode.FuncAdd, BlendingFactorDest.OneMinusSrcAlpha,
BlendingFactorSrc.One, BlendEquationMode.FuncAdd, BlendingFactorDest.Zero);
}
public IBlendState BlendNoneCopy => _rsBlendNoneVerbatim;
public IBlendState BlendNoneOpaque => _rsBlendNoneOpaque;
public IBlendState BlendNormal => _rsBlendNormal;
public void DisableBlending()
=> _device.SetRenderState(RenderState.AlphaBlendEnable, false);
/// <exception cref="InvalidOperationException">
/// <paramref name="required"/> is <see langword="true"/> and either <paramref name="vertexShader"/> or <paramref name="fragmentShader"/> is unavailable (their <see cref="Shader.Available"/> property is <see langword="false"/>), or

View File

@ -25,12 +25,6 @@ namespace BizHawk.Bizware.Graphics
public string API => "GDIPLUS";
public IBlendState CreateBlendState(BlendingFactorSrc colorSource, BlendEquationMode colorEquation, BlendingFactorDest colorDest,
BlendingFactorSrc alphaSource, BlendEquationMode alphaEquation, BlendingFactorDest alphaDest)
{
return null;
}
public void FreeTexture(Texture2d tex)
{
var gtex = (GDIPlusTexture)tex.Opaque;
@ -43,21 +37,16 @@ namespace BizHawk.Bizware.Graphics
public Shader CreateVertexShader(string source, string entry, bool required)
=> null;
public void SetBlendState(IBlendState rsBlend)
public void EnableBlending()
{
// TODO for real
}
private class EmptyBlendState : IBlendState
public void DisableBlending()
{
// TODO for real
}
private static readonly EmptyBlendState _rsBlendNoneVerbatim = new(), _rsBlendNoneOpaque = new(), _rsBlendNormal = new();
public IBlendState BlendNoneCopy => _rsBlendNoneVerbatim;
public IBlendState BlendNoneOpaque => _rsBlendNoneOpaque;
public IBlendState BlendNormal => _rsBlendNormal;
public Pipeline CreatePipeline(VertexLayout vertexLayout, Shader vertexShader, Shader fragmentShader, bool required, string memo)
{
return null;

View File

@ -54,9 +54,6 @@ namespace BizHawk.Bizware.Graphics
}
GL = GL.GetApi(SDL2OpenGLContext.GetGLProcAddress);
// misc initialization
CreateRenderStates();
}
public void BeginScene()
@ -93,48 +90,15 @@ namespace BizHawk.Bizware.Graphics
return CreateShader(ShaderType.VertexShader, source, required);
}
public IBlendState CreateBlendState(
BlendingFactorSrc colorSource,
BlendEquationMode colorEquation,
BlendingFactorDest colorDest,
BlendingFactorSrc alphaSource,
BlendEquationMode alphaEquation,
BlendingFactorDest alphaDest)
{
return new CacheBlendState(true, colorSource, colorEquation, colorDest, alphaSource, alphaEquation, alphaDest);
}
public void SetBlendState(IBlendState rsBlend)
{
var mybs = (CacheBlendState)rsBlend;
if (mybs.Enabled)
public void EnableBlending()
{
GL.Enable(EnableCap.Blend);
// these are all casts to copies of the same enum
GL.BlendEquationSeparate(
(GLEnum)mybs.colorEquation,
(GLEnum)mybs.alphaEquation);
GL.BlendFuncSeparate(
(BlendingFactor)mybs.colorSource,
(BlendingFactor)mybs.colorDest,
(BlendingFactor)mybs.alphaSource,
(BlendingFactor)mybs.alphaDest);
}
else
{
GL.Disable(EnableCap.Blend);
GL.BlendEquation(GLEnum.FuncAdd);
GL.BlendFuncSeparate(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha, BlendingFactor.One, BlendingFactor.Zero);
}
if (rsBlend == _rsBlendNoneOpaque)
{
//make sure constant color is set correctly
GL.BlendColor(Color.FromArgb(255, 255, 255, 255));
}
}
public IBlendState BlendNoneCopy => _rsBlendNoneVerbatim;
public IBlendState BlendNoneOpaque => _rsBlendNoneOpaque;
public IBlendState BlendNormal => _rsBlendNormal;
public void DisableBlending()
=> GL.Disable(EnableCap.Blend);
private class ShaderWrapper
{
@ -809,25 +773,5 @@ namespace BizHawk.Bizware.Graphics
return success;
}
private void CreateRenderStates()
{
_rsBlendNoneVerbatim = new(
false,
BlendingFactorSrc.One, BlendEquationMode.FuncAdd, BlendingFactorDest.Zero,
BlendingFactorSrc.One, BlendEquationMode.FuncAdd, BlendingFactorDest.Zero);
_rsBlendNoneOpaque = new(
false,
BlendingFactorSrc.One, BlendEquationMode.FuncAdd, BlendingFactorDest.Zero,
BlendingFactorSrc.ConstantAlpha, BlendEquationMode.FuncAdd, BlendingFactorDest.Zero);
_rsBlendNormal = new(
true,
BlendingFactorSrc.SrcAlpha, BlendEquationMode.FuncAdd, BlendingFactorDest.OneMinusSrcAlpha,
BlendingFactorSrc.One, BlendEquationMode.FuncAdd, BlendingFactorDest.Zero);
}
private CacheBlendState _rsBlendNoneVerbatim, _rsBlendNoneOpaque, _rsBlendNormal;
}
}

View File

@ -1,42 +0,0 @@
using BizHawk.Bizware.BizwareGL;
namespace BizHawk.Bizware.Graphics
{
/// <summary>
/// An IBlendState token that just caches all the args needed to create a blend state
/// </summary>
public class CacheBlendState : IBlendState
{
public readonly bool Enabled;
public readonly BlendingFactorSrc colorSource;
public readonly BlendEquationMode colorEquation;
public readonly BlendingFactorDest colorDest;
public readonly BlendingFactorSrc alphaSource;
public readonly BlendEquationMode alphaEquation;
public readonly BlendingFactorDest alphaDest;
public CacheBlendState(
bool enabled,
BlendingFactorSrc colorSource,
BlendEquationMode colorEquation,
BlendingFactorDest colorDest,
BlendingFactorSrc alphaSource,
BlendEquationMode alphaEquation,
BlendingFactorDest alphaDest)
{
this.Enabled = enabled;
this.colorSource = colorSource;
this.colorEquation = colorEquation;
this.colorDest = colorDest;
this.alphaSource = alphaSource;
this.alphaEquation = alphaEquation;
this.alphaDest = alphaDest;
}
}
}

View File

@ -95,12 +95,13 @@ namespace BizHawk.Bizware.Graphics
CurrentImageAttributes.SetColorMatrix(colorMatrix,ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
}
private IBlendState CurrentBlendState;
private bool _enableBlending;
public void SetBlendState(IBlendState rsBlend)
{
CurrentBlendState = rsBlend;
}
public void EnableBlending()
=> _enableBlending = true;
public void DisableBlending()
=> _enableBlending = false;
private MatrixStack _Projection, _Modelview;
@ -133,8 +134,6 @@ namespace BizHawk.Bizware.Graphics
{
Begin();
CurrentBlendState = _gdi.BlendNormal;
Projection = Owner.CreateGuiProjectionMatrix(width, height);
Modelview = Owner.CreateGuiViewMatrix(width, height);
}
@ -143,7 +142,11 @@ namespace BizHawk.Bizware.Graphics
{
// uhhmmm I want to throw an exception if its already active, but its annoying.
IsActive = true;
_enableBlending = false;
CurrentImageAttributes = new();
Modelview.Clear();
Projection.Clear();
}
public void Flush()
@ -222,14 +225,12 @@ namespace BizHawk.Bizware.Graphics
_ => g.InterpolationMode
};
if (CurrentBlendState == _gdi.BlendNormal)
if (_enableBlending)
{
g.CompositingMode = CompositingMode.SourceOver;
g.CompositingQuality = CompositingQuality.Default; // ?
}
else
// if (CurrentBlendState == Gdi.BlendNoneCopy)
// if (CurrentBlendState == Gdi.BlendNoneOpaque)
{
g.CompositingMode = CompositingMode.SourceCopy;
g.CompositingQuality = CompositingQuality.HighSpeed;

View File

@ -1,11 +1,6 @@
//http://stackoverflow.com/questions/6893302/decode-rgb-value-to-single-float-without-bit-shift-in-glsl
//why this stupid assert on the blendstate. just set one by default, geeze.
using System;
#if DEBUG
using System.Diagnostics;
#endif
using System.Drawing;
using System.Numerics;
@ -113,13 +108,16 @@ namespace BizHawk.Bizware.Graphics
CurrPipeline["uModulateColor"].Set(new Vector4(color.R / 255.0f, color.G / 255.0f, color.B / 255.0f, color.A / 255.0f));
}
public void SetBlendState(IBlendState rsBlend)
public void EnableBlending()
{
#if DEBUG
BlendStateSet = true;
#endif
Flush();
Owner.SetBlendState(rsBlend);
Owner.EnableBlending();
}
public void DisableBlending()
{
Flush();
Owner.DisableBlending();
}
private MatrixStack _Projection, _Modelview;
@ -142,7 +140,10 @@ namespace BizHawk.Bizware.Graphics
}
}
public void Begin(Size size) { Begin(size.Width, size.Height); }
public void Begin(Size size)
{
Begin(size.Width, size.Height);
}
public void Begin(int width, int height)
{
@ -160,10 +161,13 @@ namespace BizHawk.Bizware.Graphics
// uhhmmm I want to throw an exception if its already active, but its annoying.
if (CurrPipeline == null)
{
throw new InvalidOperationException("Pipeline hasn't been set!");
}
IsActive = true;
Owner.BindPipeline(CurrPipeline);
Owner.DisableBlending();
//clear state cache
sTexture = null;
@ -171,10 +175,6 @@ namespace BizHawk.Bizware.Graphics
Modelview.Clear();
Projection.Clear();
SetModulateColorWhite();
#if DEBUG
BlendStateSet = false;
#endif
}

View File

@ -300,7 +300,7 @@ namespace BizHawk.Client.Common
{
ClipBounds = new Rectangle(0, 0, size.Width, size.Height)
};
_renderer.SetBlendState(_gl.BlendNormal);
_renderer.EnableBlending();
OSD.Begin(myBlitter);
OSD.DrawScreenInfo(myBlitter);
OSD.DrawMessages(myBlitter);

View File

@ -398,7 +398,7 @@ namespace BizHawk.Client.Common.Filters
FilterProgram.GL.ClearColor(Color.Black);
FilterProgram.GuiRenderer.Begin(outputSize);
FilterProgram.GuiRenderer.SetBlendState(FilterProgram.GL.BlendNoneCopy);
FilterProgram.GuiRenderer.DisableBlending();
// TODO: may depend on input, or other factors, not sure yet
// watch out though... if we filter linear, then screens will bleed into each other.
@ -664,7 +664,7 @@ namespace BizHawk.Client.Common.Filters
FilterProgram.GL.ClearColor(Color.FromArgb(BackgroundColor));
FilterProgram.GuiRenderer.Begin(OutputSize.Width, OutputSize.Height);
FilterProgram.GuiRenderer.SetBlendState(FilterProgram.GL.BlendNoneCopy);
FilterProgram.GuiRenderer.DisableBlending();
if (FilterOption != eFilterOption.None)
{
@ -708,7 +708,7 @@ namespace BizHawk.Client.Common.Filters
{
var outSize = FindOutput().SurfaceFormat.Size;
FilterProgram.GuiRenderer.Begin(outSize);
FilterProgram.GuiRenderer.SetBlendState(FilterProgram.GL.BlendNoneCopy);
FilterProgram.GuiRenderer.DisableBlending();
FilterProgram.GuiRenderer.Modelview.Scale(Scale);
FilterProgram.GuiRenderer.Draw(InputTexture);
FilterProgram.GuiRenderer.End();
@ -763,7 +763,7 @@ namespace BizHawk.Client.Common.Filters
public override void Run()
{
FilterProgram.GuiRenderer.Begin(OutputSize); // hope this didn't change
FilterProgram.GuiRenderer.SetBlendState(FilterProgram.GL.BlendNoneCopy);
FilterProgram.GuiRenderer.DisableBlending();
FilterProgram.GuiRenderer.Modelview.Scale(XIS,YIS);
FilterProgram.GuiRenderer.Draw(InputTexture);
FilterProgram.GuiRenderer.End();
@ -794,7 +794,7 @@ namespace BizHawk.Client.Common.Filters
{
var outSize = FindOutput().SurfaceFormat.Size;
FilterProgram.GuiRenderer.Begin(outSize);
FilterProgram.GuiRenderer.SetBlendState(FilterProgram.GL.BlendNormal);
FilterProgram.GuiRenderer.EnableBlending();
FilterProgram.GuiRenderer.Draw(_texture);
FilterProgram.GuiRenderer.End();
}

View File

@ -51,7 +51,7 @@ namespace BizHawk.Client.Common.Filters
{
var renderer = FilterProgram.GuiRenderer;
renderer.Begin(FindOutput().SurfaceFormat.Size);
renderer.SetBlendState(FilterProgram.GL.BlendNoneCopy);
renderer.DisableBlending();
renderer.Draw(InputTexture);
renderer.End();
}

View File

@ -101,7 +101,7 @@ namespace BizHawk.Client.EmuHawk
}
_guiRenderer.Begin(Width, Height);
_guiRenderer.SetBlendState(_gl.BlendNoneCopy);
_guiRenderer.DisableBlending();
_guiRenderer.Draw(_rt.Texture2d);
_guiRenderer.End();
_graphicsControl.SwapBuffers();