Implement HLE macros for render target clears (#3528)
* Implement HLE macros for render target clears * Add constants for the offsets
This commit is contained in:
parent
c48a75979f
commit
1080f64df9
16 changed files with 149 additions and 43 deletions
|
@ -11,10 +11,11 @@ namespace Ryujinx.Graphics.GAL
|
||||||
|
|
||||||
void ClearBuffer(BufferHandle destination, int offset, int size, uint value);
|
void ClearBuffer(BufferHandle destination, int offset, int size, uint value);
|
||||||
|
|
||||||
void ClearRenderTargetColor(int index, int layer, uint componentMask, ColorF color);
|
void ClearRenderTargetColor(int index, int layer, int layerCount, uint componentMask, ColorF color);
|
||||||
|
|
||||||
void ClearRenderTargetDepthStencil(
|
void ClearRenderTargetDepthStencil(
|
||||||
int layer,
|
int layer,
|
||||||
|
int layerCount,
|
||||||
float depthValue,
|
float depthValue,
|
||||||
bool depthMask,
|
bool depthMask,
|
||||||
int stencilValue,
|
int stencilValue,
|
||||||
|
|
|
@ -5,20 +5,22 @@
|
||||||
public CommandType CommandType => CommandType.ClearRenderTargetColor;
|
public CommandType CommandType => CommandType.ClearRenderTargetColor;
|
||||||
private int _index;
|
private int _index;
|
||||||
private int _layer;
|
private int _layer;
|
||||||
|
private int _layerCount;
|
||||||
private uint _componentMask;
|
private uint _componentMask;
|
||||||
private ColorF _color;
|
private ColorF _color;
|
||||||
|
|
||||||
public void Set(int index, int layer, uint componentMask, ColorF color)
|
public void Set(int index, int layer, int layerCount, uint componentMask, ColorF color)
|
||||||
{
|
{
|
||||||
_index = index;
|
_index = index;
|
||||||
_layer = layer;
|
_layer = layer;
|
||||||
|
_layerCount = layerCount;
|
||||||
_componentMask = componentMask;
|
_componentMask = componentMask;
|
||||||
_color = color;
|
_color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Run(ref ClearRenderTargetColorCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
public static void Run(ref ClearRenderTargetColorCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||||
{
|
{
|
||||||
renderer.Pipeline.ClearRenderTargetColor(command._index, command._layer, command._componentMask, command._color);
|
renderer.Pipeline.ClearRenderTargetColor(command._index, command._layer, command._layerCount, command._componentMask, command._color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,16 @@
|
||||||
{
|
{
|
||||||
public CommandType CommandType => CommandType.ClearRenderTargetDepthStencil;
|
public CommandType CommandType => CommandType.ClearRenderTargetDepthStencil;
|
||||||
private int _layer;
|
private int _layer;
|
||||||
|
private int _layerCount;
|
||||||
private float _depthValue;
|
private float _depthValue;
|
||||||
private bool _depthMask;
|
private bool _depthMask;
|
||||||
private int _stencilValue;
|
private int _stencilValue;
|
||||||
private int _stencilMask;
|
private int _stencilMask;
|
||||||
|
|
||||||
public void Set(int layer, float depthValue, bool depthMask, int stencilValue, int stencilMask)
|
public void Set(int layer, int layerCount, float depthValue, bool depthMask, int stencilValue, int stencilMask)
|
||||||
{
|
{
|
||||||
_layer = layer;
|
_layer = layer;
|
||||||
|
_layerCount = layerCount;
|
||||||
_depthValue = depthValue;
|
_depthValue = depthValue;
|
||||||
_depthMask = depthMask;
|
_depthMask = depthMask;
|
||||||
_stencilValue = stencilValue;
|
_stencilValue = stencilValue;
|
||||||
|
@ -20,7 +22,7 @@
|
||||||
|
|
||||||
public static void Run(ref ClearRenderTargetDepthStencilCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
public static void Run(ref ClearRenderTargetDepthStencilCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||||
{
|
{
|
||||||
renderer.Pipeline.ClearRenderTargetDepthStencil(command._layer, command._depthValue, command._depthMask, command._stencilValue, command._stencilMask);
|
renderer.Pipeline.ClearRenderTargetDepthStencil(command._layer, command._layerCount, command._depthValue, command._depthMask, command._stencilValue, command._stencilMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,15 +41,15 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearRenderTargetColor(int index, int layer, uint componentMask, ColorF color)
|
public void ClearRenderTargetColor(int index, int layer, int layerCount, uint componentMask, ColorF color)
|
||||||
{
|
{
|
||||||
_renderer.New<ClearRenderTargetColorCommand>().Set(index, layer, componentMask, color);
|
_renderer.New<ClearRenderTargetColorCommand>().Set(index, layer, layerCount, componentMask, color);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearRenderTargetDepthStencil(int layer, float depthValue, bool depthMask, int stencilValue, int stencilMask)
|
public void ClearRenderTargetDepthStencil(int layer, int layerCount, float depthValue, bool depthMask, int stencilValue, int stencilMask)
|
||||||
{
|
{
|
||||||
_renderer.New<ClearRenderTargetDepthStencilCommand>().Set(layer, depthValue, depthMask, stencilValue, stencilMask);
|
_renderer.New<ClearRenderTargetDepthStencilCommand>().Set(layer, layerCount, depthValue, depthMask, stencilValue, stencilMask);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ using Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer;
|
||||||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||||
using Ryujinx.Graphics.GAL.Multithreading.Resources.Programs;
|
using Ryujinx.Graphics.GAL.Multithreading.Resources.Programs;
|
||||||
using Ryujinx.Graphics.Shader;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
|
@ -12,6 +12,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class MacroHLE : IMacroEE
|
class MacroHLE : IMacroEE
|
||||||
{
|
{
|
||||||
|
private const int ColorLayerCountOffset = 0x818;
|
||||||
|
private const int ColorStructSize = 0x40;
|
||||||
|
private const int ZetaLayerCountOffset = 0x1230;
|
||||||
|
|
||||||
private readonly GPFifoProcessor _processor;
|
private readonly GPFifoProcessor _processor;
|
||||||
private readonly MacroHLEFunctionName _functionName;
|
private readonly MacroHLEFunctionName _functionName;
|
||||||
|
|
||||||
|
@ -45,6 +49,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
||||||
{
|
{
|
||||||
switch (_functionName)
|
switch (_functionName)
|
||||||
{
|
{
|
||||||
|
case MacroHLEFunctionName.ClearColor:
|
||||||
|
ClearColor(state, arg0);
|
||||||
|
break;
|
||||||
|
case MacroHLEFunctionName.ClearDepthStencil:
|
||||||
|
ClearDepthStencil(state, arg0);
|
||||||
|
break;
|
||||||
case MacroHLEFunctionName.MultiDrawElementsIndirectCount:
|
case MacroHLEFunctionName.MultiDrawElementsIndirectCount:
|
||||||
MultiDrawElementsIndirectCount(state, arg0);
|
MultiDrawElementsIndirectCount(state, arg0);
|
||||||
break;
|
break;
|
||||||
|
@ -53,6 +63,31 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears one bound color target.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="state">GPU state at the time of the call</param>
|
||||||
|
/// <param name="arg0">First argument of the call</param>
|
||||||
|
private void ClearColor(IDeviceState state, int arg0)
|
||||||
|
{
|
||||||
|
int index = (arg0 >> 6) & 0xf;
|
||||||
|
int layerCount = state.Read(ColorLayerCountOffset + index * ColorStructSize);
|
||||||
|
|
||||||
|
_processor.ThreedClass.Clear(arg0, layerCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears the current depth-stencil target.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="state">GPU state at the time of the call</param>
|
||||||
|
/// <param name="arg0">First argument of the call</param>
|
||||||
|
private void ClearDepthStencil(IDeviceState state, int arg0)
|
||||||
|
{
|
||||||
|
int layerCount = state.Read(ZetaLayerCountOffset);
|
||||||
|
|
||||||
|
_processor.ThreedClass.Clear(arg0, layerCount);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs a indirect multi-draw, with parameters from a GPU buffer.
|
/// Performs a indirect multi-draw, with parameters from a GPU buffer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
enum MacroHLEFunctionName
|
enum MacroHLEFunctionName
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
|
ClearColor,
|
||||||
|
ClearDepthStencil,
|
||||||
MultiDrawElementsIndirectCount
|
MultiDrawElementsIndirectCount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,12 +46,19 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
||||||
|
|
||||||
private static readonly TableEntry[] Table = new TableEntry[]
|
private static readonly TableEntry[] Table = new TableEntry[]
|
||||||
{
|
{
|
||||||
|
new TableEntry(MacroHLEFunctionName.ClearColor, new Hash128(0xA9FB28D1DC43645A, 0xB177E5D2EAE67FB0), 0x28),
|
||||||
|
new TableEntry(MacroHLEFunctionName.ClearDepthStencil, new Hash128(0x1B96CB77D4879F4F, 0x8557032FE0C965FB), 0x24),
|
||||||
new TableEntry(MacroHLEFunctionName.MultiDrawElementsIndirectCount, new Hash128(0x890AF57ED3FB1C37, 0x35D0C95C61F5386F), 0x19C)
|
new TableEntry(MacroHLEFunctionName.MultiDrawElementsIndirectCount, new Hash128(0x890AF57ED3FB1C37, 0x35D0C95C61F5386F), 0x19C)
|
||||||
};
|
};
|
||||||
|
|
||||||
private static bool IsMacroHLESupported(Capabilities caps, MacroHLEFunctionName name)
|
private static bool IsMacroHLESupported(Capabilities caps, MacroHLEFunctionName name)
|
||||||
{
|
{
|
||||||
if (name == MacroHLEFunctionName.MultiDrawElementsIndirectCount)
|
if (name == MacroHLEFunctionName.ClearColor ||
|
||||||
|
name == MacroHLEFunctionName.ClearDepthStencil)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (name == MacroHLEFunctionName.MultiDrawElementsIndirectCount)
|
||||||
{
|
{
|
||||||
return caps.SupportsIndirectParameters;
|
return caps.SupportsIndirectParameters;
|
||||||
}
|
}
|
||||||
|
|
|
@ -487,11 +487,23 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Clears the current color and depth-stencil buffers.
|
/// Clears the current color and depth-stencil buffers.
|
||||||
/// Which buffers should be cleared is also specified on the argument.
|
/// Which buffers should be cleared can also be specified with the argument.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="engine">3D engine where this method is being called</param>
|
/// <param name="engine">3D engine where this method is being called</param>
|
||||||
/// <param name="argument">Method call argument</param>
|
/// <param name="argument">Method call argument</param>
|
||||||
public void Clear(ThreedClass engine, int argument)
|
public void Clear(ThreedClass engine, int argument)
|
||||||
|
{
|
||||||
|
Clear(engine, argument, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears the current color and depth-stencil buffers.
|
||||||
|
/// Which buffers should be cleared can also specified with the arguments.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="engine">3D engine where this method is being called</param>
|
||||||
|
/// <param name="argument">Method call argument</param>
|
||||||
|
/// <param name="layerCount">For array and 3D textures, indicates how many layers should be cleared</param>
|
||||||
|
public void Clear(ThreedClass engine, int argument, int layerCount)
|
||||||
{
|
{
|
||||||
ConditionalRenderEnabled renderEnable = ConditionalRendering.GetRenderEnable(
|
ConditionalRenderEnabled renderEnable = ConditionalRendering.GetRenderEnable(
|
||||||
_context,
|
_context,
|
||||||
|
@ -507,7 +519,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
int index = (argument >> 6) & 0xf;
|
int index = (argument >> 6) & 0xf;
|
||||||
int layer = (argument >> 10) & 0x3ff;
|
int layer = (argument >> 10) & 0x3ff;
|
||||||
|
|
||||||
engine.UpdateRenderTargetState(useControl: false, layered: layer != 0, singleUse: index);
|
engine.UpdateRenderTargetState(useControl: false, layered: layer != 0 || layerCount > 1, singleUse: index);
|
||||||
|
|
||||||
// If there is a mismatch on the host clip region and the one explicitly defined by the guest
|
// If there is a mismatch on the host clip region and the one explicitly defined by the guest
|
||||||
// on the screen scissor state, then we need to force only one texture to be bound to avoid
|
// on the screen scissor state, then we need to force only one texture to be bound to avoid
|
||||||
|
@ -578,7 +590,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
|
|
||||||
bool clearDepth = (argument & 1) != 0;
|
bool clearDepth = (argument & 1) != 0;
|
||||||
bool clearStencil = (argument & 2) != 0;
|
bool clearStencil = (argument & 2) != 0;
|
||||||
|
|
||||||
uint componentMask = (uint)((argument >> 2) & 0xf);
|
uint componentMask = (uint)((argument >> 2) & 0xf);
|
||||||
|
|
||||||
if (componentMask != 0)
|
if (componentMask != 0)
|
||||||
|
@ -587,7 +598,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
|
|
||||||
ColorF color = new ColorF(clearColor.Red, clearColor.Green, clearColor.Blue, clearColor.Alpha);
|
ColorF color = new ColorF(clearColor.Red, clearColor.Green, clearColor.Blue, clearColor.Alpha);
|
||||||
|
|
||||||
_context.Renderer.Pipeline.ClearRenderTargetColor(index, layer, componentMask, color);
|
_context.Renderer.Pipeline.ClearRenderTargetColor(index, layer, layerCount, componentMask, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clearDepth || clearStencil)
|
if (clearDepth || clearStencil)
|
||||||
|
@ -609,6 +620,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
|
|
||||||
_context.Renderer.Pipeline.ClearRenderTargetDepthStencil(
|
_context.Renderer.Pipeline.ClearRenderTargetDepthStencil(
|
||||||
layer,
|
layer,
|
||||||
|
layerCount,
|
||||||
depthValue,
|
depthValue,
|
||||||
clearDepth,
|
clearDepth,
|
||||||
stencilValue,
|
stencilValue,
|
||||||
|
|
|
@ -497,6 +497,17 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears the current color and depth-stencil buffers.
|
||||||
|
/// Which buffers should be cleared can also specified with the arguments.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="argument">Method call argument</param>
|
||||||
|
/// <param name="layerCount">For array and 3D textures, indicates how many layers should be cleared</param>
|
||||||
|
public void Clear(int argument, int layerCount)
|
||||||
|
{
|
||||||
|
_drawManager.Clear(this, argument, layerCount);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs a indirect multi-draw, with parameters from a GPU buffer.
|
/// Performs a indirect multi-draw, with parameters from a GPU buffer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -145,6 +145,16 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
return format == Format.D16Unorm || format == Format.D32Float;
|
return format == Format.D16Unorm || format == Format.D32Float;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int GetColorLayerCount(int index)
|
||||||
|
{
|
||||||
|
return _colors[index].Info.GetDepthOrLayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetDepthStencilLayerCount()
|
||||||
|
{
|
||||||
|
return _depthStencil?.Info.GetDepthOrLayers() ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
public void AttachColorLayerForClear(int index, int layer)
|
public void AttachColorLayerForClear(int index, int layer)
|
||||||
{
|
{
|
||||||
TextureView color = _colors[index];
|
TextureView color = _colors[index];
|
||||||
|
|
|
@ -110,7 +110,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
Buffer.Clear(destination, offset, size, value);
|
Buffer.Clear(destination, offset, size, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearRenderTargetColor(int index, int layer, uint componentMask, ColorF color)
|
public void ClearRenderTargetColor(int index, int layer, int layerCount, uint componentMask, ColorF color)
|
||||||
{
|
{
|
||||||
GL.ColorMask(
|
GL.ColorMask(
|
||||||
index,
|
index,
|
||||||
|
@ -119,18 +119,28 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
(componentMask & 4) != 0,
|
(componentMask & 4) != 0,
|
||||||
(componentMask & 8) != 0);
|
(componentMask & 8) != 0);
|
||||||
|
|
||||||
_framebuffer.AttachColorLayerForClear(index, layer);
|
|
||||||
|
|
||||||
float[] colors = new float[] { color.Red, color.Green, color.Blue, color.Alpha };
|
float[] colors = new float[] { color.Red, color.Green, color.Blue, color.Alpha };
|
||||||
|
|
||||||
GL.ClearBuffer(OpenTK.Graphics.OpenGL.ClearBuffer.Color, index, colors);
|
if (layer != 0 || layerCount != _framebuffer.GetColorLayerCount(index))
|
||||||
|
{
|
||||||
|
for (int l = layer; l < layer + layerCount; l++)
|
||||||
|
{
|
||||||
|
_framebuffer.AttachColorLayerForClear(index, l);
|
||||||
|
|
||||||
_framebuffer.DetachColorLayerForClear(index);
|
GL.ClearBuffer(OpenTK.Graphics.OpenGL.ClearBuffer.Color, index, colors);
|
||||||
|
}
|
||||||
|
|
||||||
|
_framebuffer.DetachColorLayerForClear(index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GL.ClearBuffer(OpenTK.Graphics.OpenGL.ClearBuffer.Color, index, colors);
|
||||||
|
}
|
||||||
|
|
||||||
RestoreComponentMask(index);
|
RestoreComponentMask(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearRenderTargetDepthStencil(int layer, float depthValue, bool depthMask, int stencilValue, int stencilMask)
|
public void ClearRenderTargetDepthStencil(int layer, int layerCount, float depthValue, bool depthMask, int stencilValue, int stencilMask)
|
||||||
{
|
{
|
||||||
bool stencilMaskChanged =
|
bool stencilMaskChanged =
|
||||||
stencilMask != 0 &&
|
stencilMask != 0 &&
|
||||||
|
@ -148,8 +158,35 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
GL.DepthMask(depthMask);
|
GL.DepthMask(depthMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
_framebuffer.AttachDepthStencilLayerForClear(layer);
|
if (layer != 0 || layerCount != _framebuffer.GetDepthStencilLayerCount())
|
||||||
|
{
|
||||||
|
for (int l = layer; l < layer + layerCount; l++)
|
||||||
|
{
|
||||||
|
_framebuffer.AttachDepthStencilLayerForClear(l);
|
||||||
|
|
||||||
|
ClearDepthStencil(depthValue, depthMask, stencilValue, stencilMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
_framebuffer.DetachDepthStencilLayerForClear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClearDepthStencil(depthValue, depthMask, stencilValue, stencilMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stencilMaskChanged)
|
||||||
|
{
|
||||||
|
GL.StencilMaskSeparate(StencilFace.Front, _stencilFrontMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depthMaskChanged)
|
||||||
|
{
|
||||||
|
GL.DepthMask(_depthMask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ClearDepthStencil(float depthValue, bool depthMask, int stencilValue, int stencilMask)
|
||||||
|
{
|
||||||
if (depthMask && stencilMask != 0)
|
if (depthMask && stencilMask != 0)
|
||||||
{
|
{
|
||||||
GL.ClearBuffer(ClearBufferCombined.DepthStencil, 0, depthValue, stencilValue);
|
GL.ClearBuffer(ClearBufferCombined.DepthStencil, 0, depthValue, stencilValue);
|
||||||
|
@ -162,18 +199,6 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
GL.ClearBuffer(OpenTK.Graphics.OpenGL.ClearBuffer.Stencil, 0, ref stencilValue);
|
GL.ClearBuffer(OpenTK.Graphics.OpenGL.ClearBuffer.Stencil, 0, ref stencilValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
_framebuffer.DetachDepthStencilLayerForClear();
|
|
||||||
|
|
||||||
if (stencilMaskChanged)
|
|
||||||
{
|
|
||||||
GL.StencilMaskSeparate(StencilFace.Front, _stencilFrontMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (depthMaskChanged)
|
|
||||||
{
|
|
||||||
GL.DepthMask(_depthMask);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CommandBufferBarrier()
|
public void CommandBufferBarrier()
|
||||||
|
|
|
@ -149,14 +149,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return texture is TextureView view && view.Valid;
|
return texture is TextureView view && view.Valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClearRect GetClearRect(Rectangle<int> scissor, int layer)
|
public ClearRect GetClearRect(Rectangle<int> scissor, int layer, int layerCount)
|
||||||
{
|
{
|
||||||
int x = scissor.X;
|
int x = scissor.X;
|
||||||
int y = scissor.Y;
|
int y = scissor.Y;
|
||||||
int width = Math.Min((int)Width - scissor.X, scissor.Width);
|
int width = Math.Min((int)Width - scissor.X, scissor.Width);
|
||||||
int height = Math.Min((int)Height - scissor.Y, scissor.Height);
|
int height = Math.Min((int)Height - scissor.Y, scissor.Height);
|
||||||
|
|
||||||
return new ClearRect(new Rect2D(new Offset2D(x, y), new Extent2D((uint)width, (uint)height)), (uint)layer, 1);
|
return new ClearRect(new Rect2D(new Offset2D(x, y), new Extent2D((uint)width, (uint)height)), (uint)layer, (uint)layerCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe Auto<DisposableFramebuffer> Create(Vk api, CommandBufferScoped cbs, Auto<DisposableRenderPass> renderPass)
|
public unsafe Auto<DisposableFramebuffer> Create(Vk api, CommandBufferScoped cbs, Auto<DisposableRenderPass> renderPass)
|
||||||
|
|
|
@ -157,7 +157,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
if (clearAlpha)
|
if (clearAlpha)
|
||||||
{
|
{
|
||||||
_pipeline.ClearRenderTargetColor(0, 0, new ColorF(0f, 0f, 0f, 1f));
|
_pipeline.ClearRenderTargetColor(0, 0, 1, new ColorF(0f, 0f, 0f, 1f));
|
||||||
}
|
}
|
||||||
|
|
||||||
_pipeline.SetViewports(viewports, false);
|
_pipeline.SetViewports(viewports, false);
|
||||||
|
|
|
@ -162,7 +162,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
size);
|
size);
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void ClearRenderTargetColor(int index, int layer, ColorF color)
|
public unsafe void ClearRenderTargetColor(int index, int layer, int layerCount, ColorF color)
|
||||||
{
|
{
|
||||||
if (FramebufferParams == null || !FramebufferParams.IsValidColorAttachment(index))
|
if (FramebufferParams == null || !FramebufferParams.IsValidColorAttachment(index))
|
||||||
{
|
{
|
||||||
|
@ -178,12 +178,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
var clearValue = new ClearValue(new ClearColorValue(color.Red, color.Green, color.Blue, color.Alpha));
|
var clearValue = new ClearValue(new ClearColorValue(color.Red, color.Green, color.Blue, color.Alpha));
|
||||||
var attachment = new ClearAttachment(ImageAspectFlags.ImageAspectColorBit, (uint)index, clearValue);
|
var attachment = new ClearAttachment(ImageAspectFlags.ImageAspectColorBit, (uint)index, clearValue);
|
||||||
var clearRect = FramebufferParams?.GetClearRect(ClearScissor, layer) ?? default;
|
var clearRect = FramebufferParams.GetClearRect(ClearScissor, layer, layerCount);
|
||||||
|
|
||||||
Gd.Api.CmdClearAttachments(CommandBuffer, 1, &attachment, 1, &clearRect);
|
Gd.Api.CmdClearAttachments(CommandBuffer, 1, &attachment, 1, &clearRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void ClearRenderTargetDepthStencil(int layer, float depthValue, bool depthMask, int stencilValue, int stencilMask)
|
public unsafe void ClearRenderTargetDepthStencil(int layer, int layerCount, float depthValue, bool depthMask, int stencilValue, int stencilMask)
|
||||||
{
|
{
|
||||||
// TODO: Use stencilMask (fully)
|
// TODO: Use stencilMask (fully)
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
|
|
||||||
var attachment = new ClearAttachment(flags, 0, clearValue);
|
var attachment = new ClearAttachment(flags, 0, clearValue);
|
||||||
var clearRect = FramebufferParams?.GetClearRect(ClearScissor, layer) ?? default;
|
var clearRect = FramebufferParams.GetClearRect(ClearScissor, layer, layerCount);
|
||||||
|
|
||||||
Gd.Api.CmdClearAttachments(CommandBuffer, 1, &attachment, 1, &clearRect);
|
Gd.Api.CmdClearAttachments(CommandBuffer, 1, &attachment, 1, &clearRect);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_pendingQueryCopies.Clear();
|
_pendingQueryCopies.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearRenderTargetColor(int index, int layer, uint componentMask, ColorF color)
|
public void ClearRenderTargetColor(int index, int layer, int layerCount, uint componentMask, ColorF color)
|
||||||
{
|
{
|
||||||
if (FramebufferParams == null)
|
if (FramebufferParams == null)
|
||||||
{
|
{
|
||||||
|
@ -85,7 +85,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ClearRenderTargetColor(index, layer, color);
|
ClearRenderTargetColor(index, layer, layerCount, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue