Use device features to enable to disable LogicOp Extended Dynamic State
Improve index counting
This commit is contained in:
parent
b5574ac65f
commit
d5f9ed6a2e
6 changed files with 173 additions and 102 deletions
|
@ -84,8 +84,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private bool _tfEnabled;
|
private bool _tfEnabled;
|
||||||
private bool _tfActive;
|
private bool _tfActive;
|
||||||
|
|
||||||
private bool _supportExtDynamic;
|
private readonly bool _supportExtDynamic;
|
||||||
private bool _supportExtDynamic2;
|
private readonly bool _supportExtDynamic2;
|
||||||
|
|
||||||
private readonly PipelineColorBlendAttachmentState[] _storedBlend;
|
private readonly PipelineColorBlendAttachmentState[] _storedBlend;
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_storedBlend = new PipelineColorBlendAttachmentState[Constants.MaxRenderTargets];
|
_storedBlend = new PipelineColorBlendAttachmentState[Constants.MaxRenderTargets];
|
||||||
|
|
||||||
_supportExtDynamic = gd.Capabilities.SupportsExtendedDynamicState;
|
_supportExtDynamic = gd.Capabilities.SupportsExtendedDynamicState;
|
||||||
|
|
||||||
_supportExtDynamic2 = gd.Capabilities.SupportsExtendedDynamicState2;
|
_supportExtDynamic2 = gd.Capabilities.SupportsExtendedDynamicState2;
|
||||||
|
|
||||||
|
|
||||||
|
@ -714,7 +714,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_newState.DepthTestEnable = false;
|
_newState.DepthTestEnable = false;
|
||||||
_newState.DepthWriteEnable = false;
|
_newState.DepthWriteEnable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
|
|
||||||
Gd.HelperShader.DrawTexture(
|
Gd.HelperShader.DrawTexture(
|
||||||
|
@ -739,7 +739,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_newState.DepthWriteEnable = oldDepthWriteEnable;
|
_newState.DepthWriteEnable = oldDepthWriteEnable;
|
||||||
_newState.ViewportsCount = oldViewportsCount;
|
_newState.ViewportsCount = oldViewportsCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
_newState.Topology = oldTopology;
|
_newState.Topology = oldTopology;
|
||||||
|
|
||||||
DynamicState.SetViewports(ref oldViewports, oldViewportsCount);
|
DynamicState.SetViewports(ref oldViewports, oldViewportsCount);
|
||||||
|
@ -880,7 +880,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
_newState.DepthBiasEnable = enables != 0;
|
_newState.DepthBiasEnable = enables != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -913,7 +913,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_newState.DepthWriteEnable = depthTest.WriteEnable;
|
_newState.DepthWriteEnable = depthTest.WriteEnable;
|
||||||
_newState.DepthCompareOp = depthTest.Func.Convert();
|
_newState.DepthCompareOp = depthTest.Func.Convert();
|
||||||
}
|
}
|
||||||
|
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -980,14 +980,22 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
DynamicState.SetLineWidth(Gd.Capabilities.SupportsWideLines ? width : 1.0f);
|
DynamicState.SetLineWidth(Gd.Capabilities.SupportsWideLines ? width : 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetLogicOpState(bool enable, LogicalOp op)
|
public void SetLogicOpState(bool enable, LogicalOp op)
|
||||||
{
|
{
|
||||||
|
if (_supportExtDynamic2 && Gd.ExtendedLogicOp)
|
||||||
|
{
|
||||||
|
DynamicState.SetLogicOp(op.Convert());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_newState.LogicOp = op.Convert();
|
||||||
|
}
|
||||||
|
|
||||||
_newState.LogicOpEnable = enable;
|
_newState.LogicOpEnable = enable;
|
||||||
_newState.LogicOp = op.Convert();
|
|
||||||
|
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
@ -1031,9 +1039,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_topology = topology;
|
_topology = topology;
|
||||||
|
|
||||||
var vkTopology = Gd.TopologyRemap(topology).Convert();
|
var vkTopology = Gd.TopologyRemap(topology).Convert();
|
||||||
|
|
||||||
_newState.Topology = vkTopology;
|
_newState.Topology = vkTopology;
|
||||||
|
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1194,7 +1202,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
stencilTest.FrontDpPass.Convert(),
|
stencilTest.FrontDpPass.Convert(),
|
||||||
stencilTest.FrontDpFail.Convert(),
|
stencilTest.FrontDpFail.Convert(),
|
||||||
stencilTest.FrontFunc.Convert());
|
stencilTest.FrontFunc.Convert());
|
||||||
|
|
||||||
DynamicState.SetStencilTest(stencilTest.TestEnable);
|
DynamicState.SetStencilTest(stencilTest.TestEnable);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1209,7 +1217,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_newState.StencilFrontCompareOp = stencilTest.FrontFunc.Convert();
|
_newState.StencilFrontCompareOp = stencilTest.FrontFunc.Convert();
|
||||||
_newState.StencilTestEnable = stencilTest.TestEnable;
|
_newState.StencilTestEnable = stencilTest.TestEnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicState.SetStencilMask((uint)stencilTest.BackFuncMask,
|
DynamicState.SetStencilMask((uint)stencilTest.BackFuncMask,
|
||||||
(uint)stencilTest.BackMask,
|
(uint)stencilTest.BackMask,
|
||||||
(uint)stencilTest.BackFuncRef,
|
(uint)stencilTest.BackFuncRef,
|
||||||
|
@ -1450,11 +1458,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Clamp(viewport.DepthNear),
|
Clamp(viewport.DepthNear),
|
||||||
Clamp(viewport.DepthFar)));
|
Clamp(viewport.DepthFar)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_supportExtDynamic)
|
if (!_supportExtDynamic)
|
||||||
{
|
{
|
||||||
_newState.ViewportsCount = (uint)count;
|
_newState.ViewportsCount = (uint)count;
|
||||||
}
|
}
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,9 +164,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
pipeline.DepthBoundsTestEnable = false; // Not implemented.
|
pipeline.DepthBoundsTestEnable = false; // Not implemented.
|
||||||
|
|
||||||
pipeline.DepthClampEnable = state.DepthClampEnable;
|
pipeline.DepthClampEnable = state.DepthClampEnable;
|
||||||
|
|
||||||
pipeline.DepthMode = state.DepthMode == DepthMode.MinusOneToOne;
|
pipeline.DepthMode = state.DepthMode == DepthMode.MinusOneToOne;
|
||||||
|
|
||||||
pipeline.HasDepthStencil = state.DepthStencilEnable;
|
pipeline.HasDepthStencil = state.DepthStencilEnable;
|
||||||
pipeline.LogicOpEnable = state.LogicOpEnable;
|
pipeline.LogicOpEnable = state.LogicOpEnable;
|
||||||
pipeline.LogicOp = state.LogicOp.Convert();
|
pipeline.LogicOp = state.LogicOp.Convert();
|
||||||
|
@ -188,11 +188,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
pipeline.DepthTestEnable = state.DepthTest.TestEnable;
|
pipeline.DepthTestEnable = state.DepthTest.TestEnable;
|
||||||
pipeline.DepthWriteEnable = state.DepthTest.WriteEnable;
|
pipeline.DepthWriteEnable = state.DepthTest.WriteEnable;
|
||||||
pipeline.DepthCompareOp = state.DepthTest.Func.Convert();
|
pipeline.DepthCompareOp = state.DepthTest.Func.Convert();
|
||||||
|
|
||||||
pipeline.CullMode = state.CullEnable ? state.CullMode.Convert() : CullModeFlags.None;
|
pipeline.CullMode = state.CullEnable ? state.CullMode.Convert() : CullModeFlags.None;
|
||||||
|
|
||||||
pipeline.FrontFace = state.FrontFace.Convert();
|
pipeline.FrontFace = state.FrontFace.Convert();
|
||||||
|
|
||||||
if (gd.Capabilities.SupportsMultiView)
|
if (gd.Capabilities.SupportsMultiView)
|
||||||
{
|
{
|
||||||
pipeline.ScissorsCount = Constants.MaxViewports;
|
pipeline.ScissorsCount = Constants.MaxViewports;
|
||||||
|
@ -203,7 +203,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
pipeline.ScissorsCount = 1;
|
pipeline.ScissorsCount = 1;
|
||||||
pipeline.ViewportsCount = 1;
|
pipeline.ViewportsCount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline.StencilFrontFailOp = state.StencilTest.FrontSFail.Convert();
|
pipeline.StencilFrontFailOp = state.StencilTest.FrontSFail.Convert();
|
||||||
pipeline.StencilFrontPassOp = state.StencilTest.FrontDpPass.Convert();
|
pipeline.StencilFrontPassOp = state.StencilTest.FrontDpPass.Convert();
|
||||||
pipeline.StencilFrontDepthFailOp = state.StencilTest.FrontDpFail.Convert();
|
pipeline.StencilFrontDepthFailOp = state.StencilTest.FrontDpFail.Convert();
|
||||||
|
@ -213,12 +213,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
pipeline.StencilBackPassOp = state.StencilTest.BackDpPass.Convert();
|
pipeline.StencilBackPassOp = state.StencilTest.BackDpPass.Convert();
|
||||||
pipeline.StencilBackDepthFailOp = state.StencilTest.BackDpFail.Convert();
|
pipeline.StencilBackDepthFailOp = state.StencilTest.BackDpFail.Convert();
|
||||||
pipeline.StencilBackCompareOp = state.StencilTest.BackFunc.Convert();
|
pipeline.StencilBackCompareOp = state.StencilTest.BackFunc.Convert();
|
||||||
|
|
||||||
pipeline.StencilTestEnable = state.StencilTest.TestEnable;
|
pipeline.StencilTestEnable = state.StencilTest.TestEnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline.Topology = gd.TopologyRemap(state.Topology).Convert();
|
pipeline.Topology = gd.TopologyRemap(state.Topology).Convert();
|
||||||
|
|
||||||
int vaCount = Math.Min(Constants.MaxVertexAttributes, state.VertexAttribCount);
|
int vaCount = Math.Min(Constants.MaxVertexAttributes, state.VertexAttribCount);
|
||||||
int vbCount = Math.Min(Constants.MaxVertexBuffers, state.VertexBufferCount);
|
int vbCount = Math.Min(Constants.MaxVertexBuffers, state.VertexBufferCount);
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private uint _frontCompareMask;
|
private uint _frontCompareMask;
|
||||||
private uint _frontWriteMask;
|
private uint _frontWriteMask;
|
||||||
private uint _frontReference;
|
private uint _frontReference;
|
||||||
|
|
||||||
private bool _opToo;
|
private bool _opToo;
|
||||||
private StencilOp _backfailop;
|
private StencilOp _backfailop;
|
||||||
private StencilOp _backpassop;
|
private StencilOp _backpassop;
|
||||||
|
@ -33,13 +33,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private CompareOp _frontcompareop;
|
private CompareOp _frontcompareop;
|
||||||
|
|
||||||
private float _linewidth;
|
private float _linewidth;
|
||||||
|
|
||||||
public bool _stencilTestEnable;
|
public bool _stencilTestEnable;
|
||||||
|
|
||||||
public bool _depthtestEnable;
|
public bool _depthtestEnable;
|
||||||
public bool _depthwriteEnable;
|
public bool _depthwriteEnable;
|
||||||
private CompareOp _depthCompareOp;
|
private CompareOp _depthCompareOp;
|
||||||
|
|
||||||
private Array4<float> _blendConstants;
|
private Array4<float> _blendConstants;
|
||||||
|
|
||||||
public uint ViewportsCount;
|
public uint ViewportsCount;
|
||||||
|
@ -49,7 +49,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
public FrontFace FrontFace;
|
public FrontFace FrontFace;
|
||||||
|
|
||||||
private bool _discard;
|
private bool _discard;
|
||||||
|
|
||||||
|
private LogicOp _logicOp;
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
private enum DirtyFlags
|
private enum DirtyFlags
|
||||||
{
|
{
|
||||||
|
@ -61,14 +63,15 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Viewport = 1 << 4,
|
Viewport = 1 << 4,
|
||||||
CullMode = 1 << 5,
|
CullMode = 1 << 5,
|
||||||
FrontFace = 1 << 6,
|
FrontFace = 1 << 6,
|
||||||
DepthTestBool = 1 << 7,
|
DepthTestBool = 1 << 7,
|
||||||
DepthTestCompareOp = 1 << 8,
|
DepthTestCompareOp = 1 << 8,
|
||||||
StencilTestEnable = 1 << 9,
|
StencilTestEnable = 1 << 9,
|
||||||
LineWidth = 1 << 10,
|
LineWidth = 1 << 10,
|
||||||
RasterDiscard = 1 << 11,
|
RasterDiscard = 1 << 11,
|
||||||
|
LogicOp = 1 << 12,
|
||||||
Standard = Blend | DepthBias | Scissor | Stencil | Viewport | LineWidth,
|
Standard = Blend | DepthBias | Scissor | Stencil | Viewport | LineWidth,
|
||||||
Extended = CullMode | FrontFace | DepthTestBool | DepthTestCompareOp | StencilTestEnable,
|
Extended = CullMode | FrontFace | DepthTestBool | DepthTestCompareOp | StencilTestEnable,
|
||||||
Extended2 = RasterDiscard,
|
Extended2 = RasterDiscard | LogicOp,
|
||||||
}
|
}
|
||||||
|
|
||||||
private DirtyFlags _dirty;
|
private DirtyFlags _dirty;
|
||||||
|
@ -107,14 +110,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_dirty |= DirtyFlags.DepthTestBool;
|
_dirty |= DirtyFlags.DepthTestBool;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetDepthTestCompareOp(CompareOp depthTestOp)
|
public void SetDepthTestCompareOp(CompareOp depthTestOp)
|
||||||
{
|
{
|
||||||
_depthCompareOp = depthTestOp;
|
_depthCompareOp = depthTestOp;
|
||||||
|
|
||||||
_dirty |= DirtyFlags.DepthTestCompareOp;
|
_dirty |= DirtyFlags.DepthTestCompareOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetStencilOp(StencilOp backFailOp,
|
public void SetStencilOp(StencilOp backFailOp,
|
||||||
StencilOp backPassOp,
|
StencilOp backPassOp,
|
||||||
StencilOp backDepthFailOp,
|
StencilOp backDepthFailOp,
|
||||||
|
@ -133,10 +136,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_frontpassop = frontPassOp;
|
_frontpassop = frontPassOp;
|
||||||
_frontdepthfailop = frontDepthFailOp;
|
_frontdepthfailop = frontDepthFailOp;
|
||||||
_frontcompareop = frontCompareOp;
|
_frontcompareop = frontCompareOp;
|
||||||
|
|
||||||
_opToo = true;
|
_opToo = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetStencilMask(
|
public void SetStencilMask(
|
||||||
uint backCompareMask,
|
uint backCompareMask,
|
||||||
uint backWriteMask,
|
uint backWriteMask,
|
||||||
|
@ -154,11 +157,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_dirty |= DirtyFlags.Stencil;
|
_dirty |= DirtyFlags.Stencil;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetStencilTest(bool stencilTestEnable)
|
public void SetStencilTest(bool stencilTestEnable)
|
||||||
{
|
{
|
||||||
_stencilTestEnable = stencilTestEnable;
|
_stencilTestEnable = stencilTestEnable;
|
||||||
|
|
||||||
_dirty |= DirtyFlags.StencilTestEnable;
|
_dirty |= DirtyFlags.StencilTestEnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,35 +183,42 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_dirty |= DirtyFlags.Viewport;
|
_dirty |= DirtyFlags.Viewport;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetCullMode(CullModeFlags cullMode)
|
public void SetCullMode(CullModeFlags cullMode)
|
||||||
{
|
{
|
||||||
CullMode = cullMode;
|
CullMode = cullMode;
|
||||||
|
|
||||||
_dirty |= DirtyFlags.CullMode;
|
_dirty |= DirtyFlags.CullMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetFrontFace(FrontFace frontFace)
|
public void SetFrontFace(FrontFace frontFace)
|
||||||
{
|
{
|
||||||
FrontFace = frontFace;
|
FrontFace = frontFace;
|
||||||
|
|
||||||
_dirty |= DirtyFlags.FrontFace;
|
_dirty |= DirtyFlags.FrontFace;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetLineWidth(float width)
|
public void SetLineWidth(float width)
|
||||||
{
|
{
|
||||||
_linewidth = width;
|
_linewidth = width;
|
||||||
|
|
||||||
_dirty |= DirtyFlags.LineWidth;
|
_dirty |= DirtyFlags.LineWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetRasterizerDiscard(bool discard)
|
public void SetRasterizerDiscard(bool discard)
|
||||||
{
|
{
|
||||||
_discard = discard;
|
_discard = discard;
|
||||||
|
|
||||||
_dirty |= DirtyFlags.RasterDiscard;
|
_dirty |= DirtyFlags.RasterDiscard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetLogicOp(LogicOp op)
|
||||||
|
{
|
||||||
|
_logicOp = op;
|
||||||
|
|
||||||
|
_dirty |= DirtyFlags.LogicOp;
|
||||||
|
}
|
||||||
|
|
||||||
public void ForceAllDirty(VulkanRenderer gd)
|
public void ForceAllDirty(VulkanRenderer gd)
|
||||||
{
|
{
|
||||||
_dirty = DirtyFlags.Standard;
|
_dirty = DirtyFlags.Standard;
|
||||||
|
@ -227,6 +237,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
_dirty &= ~DirtyFlags.LineWidth;
|
_dirty &= ~DirtyFlags.LineWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!gd.ExtendedLogicOp)
|
||||||
|
{
|
||||||
|
_dirty &= ~DirtyFlags.LogicOp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReplayIfDirty(VulkanRenderer gd, CommandBuffer commandBuffer)
|
public void ReplayIfDirty(VulkanRenderer gd, CommandBuffer commandBuffer)
|
||||||
|
@ -255,42 +270,47 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
RecordViewport(gd, commandBuffer);
|
RecordViewport(gd, commandBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_dirty.HasFlag(DirtyFlags.CullMode))
|
if (_dirty.HasFlag(DirtyFlags.CullMode))
|
||||||
{
|
{
|
||||||
RecordCullMode(gd.ExtendedDynamicStateApi, commandBuffer);
|
RecordCullMode(gd.ExtendedDynamicStateApi, commandBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_dirty.HasFlag(DirtyFlags.FrontFace))
|
if (_dirty.HasFlag(DirtyFlags.FrontFace))
|
||||||
{
|
{
|
||||||
RecordFrontFace(gd.ExtendedDynamicStateApi, commandBuffer);
|
RecordFrontFace(gd.ExtendedDynamicStateApi, commandBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_dirty.HasFlag(DirtyFlags.DepthTestBool))
|
if (_dirty.HasFlag(DirtyFlags.DepthTestBool))
|
||||||
{
|
{
|
||||||
RecordDepthTestBool(gd.ExtendedDynamicStateApi, commandBuffer);
|
RecordDepthTestBool(gd.ExtendedDynamicStateApi, commandBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_dirty.HasFlag(DirtyFlags.DepthTestCompareOp))
|
if (_dirty.HasFlag(DirtyFlags.DepthTestCompareOp))
|
||||||
{
|
{
|
||||||
RecordDepthTestCompareOp(gd.ExtendedDynamicStateApi, commandBuffer);
|
RecordDepthTestCompareOp(gd.ExtendedDynamicStateApi, commandBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_dirty.HasFlag(DirtyFlags.StencilTestEnable))
|
if (_dirty.HasFlag(DirtyFlags.StencilTestEnable))
|
||||||
{
|
{
|
||||||
RecordStencilTestEnable(gd.ExtendedDynamicStateApi, commandBuffer);
|
RecordStencilTestEnable(gd.ExtendedDynamicStateApi, commandBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_dirty.HasFlag(DirtyFlags.LineWidth))
|
if (_dirty.HasFlag(DirtyFlags.LineWidth))
|
||||||
{
|
{
|
||||||
RecordLineWidth(gd.Api, commandBuffer);
|
RecordLineWidth(gd.Api, commandBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_dirty.HasFlag(DirtyFlags.RasterDiscard))
|
if (_dirty.HasFlag(DirtyFlags.RasterDiscard))
|
||||||
{
|
{
|
||||||
RecordRasterizationDiscard(gd, commandBuffer);
|
RecordRasterizationDiscard(gd, commandBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_dirty.HasFlag(DirtyFlags.RasterDiscard))
|
||||||
|
{
|
||||||
|
RecordLogicOp(gd, commandBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
_dirty = DirtyFlags.None;
|
_dirty = DirtyFlags.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +322,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private readonly void RecordDepthBias(VulkanRenderer gd, CommandBuffer commandBuffer)
|
private readonly void RecordDepthBias(VulkanRenderer gd, CommandBuffer commandBuffer)
|
||||||
{
|
{
|
||||||
gd.Api.CmdSetDepthBias(commandBuffer, _depthBiasConstantFactor, _depthBiasClamp, _depthBiasSlopeFactor);
|
gd.Api.CmdSetDepthBias(commandBuffer, _depthBiasConstantFactor, _depthBiasClamp, _depthBiasSlopeFactor);
|
||||||
|
|
||||||
if (gd.Capabilities.SupportsExtendedDynamicState2)
|
if (gd.Capabilities.SupportsExtendedDynamicState2)
|
||||||
{
|
{
|
||||||
gd.ExtendedDynamicState2Api.CmdSetDepthBiasEnable(commandBuffer, _depthBiasEnable);
|
gd.ExtendedDynamicState2Api.CmdSetDepthBiasEnable(commandBuffer, _depthBiasEnable);
|
||||||
|
@ -326,7 +346,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly void RecordStencil(VulkanRenderer gd, CommandBuffer commandBuffer)
|
private readonly void RecordStencil(VulkanRenderer gd, CommandBuffer commandBuffer)
|
||||||
{
|
{
|
||||||
if (_opToo)
|
if (_opToo)
|
||||||
|
@ -336,7 +356,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
gd.ExtendedDynamicStateApi.CmdSetStencilOp(commandBuffer, StencilFaceFlags.FaceFrontBit, _frontfailop, _frontpassop,
|
gd.ExtendedDynamicStateApi.CmdSetStencilOp(commandBuffer, StencilFaceFlags.FaceFrontBit, _frontfailop, _frontpassop,
|
||||||
_frontdepthfailop, _frontcompareop);
|
_frontdepthfailop, _frontcompareop);
|
||||||
}
|
}
|
||||||
|
|
||||||
gd.Api.CmdSetStencilCompareMask(commandBuffer, StencilFaceFlags.FaceBackBit, _backCompareMask);
|
gd.Api.CmdSetStencilCompareMask(commandBuffer, StencilFaceFlags.FaceBackBit, _backCompareMask);
|
||||||
gd.Api.CmdSetStencilWriteMask(commandBuffer, StencilFaceFlags.FaceBackBit, _backWriteMask);
|
gd.Api.CmdSetStencilWriteMask(commandBuffer, StencilFaceFlags.FaceBackBit, _backWriteMask);
|
||||||
gd.Api.CmdSetStencilReference(commandBuffer, StencilFaceFlags.FaceBackBit, _backReference);
|
gd.Api.CmdSetStencilReference(commandBuffer, StencilFaceFlags.FaceBackBit, _backReference);
|
||||||
|
@ -344,12 +364,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
gd.Api.CmdSetStencilWriteMask(commandBuffer, StencilFaceFlags.FaceFrontBit, _frontWriteMask);
|
gd.Api.CmdSetStencilWriteMask(commandBuffer, StencilFaceFlags.FaceFrontBit, _frontWriteMask);
|
||||||
gd.Api.CmdSetStencilReference(commandBuffer, StencilFaceFlags.FaceFrontBit, _frontReference);
|
gd.Api.CmdSetStencilReference(commandBuffer, StencilFaceFlags.FaceFrontBit, _frontReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly void RecordStencilTestEnable(ExtExtendedDynamicState api, CommandBuffer commandBuffer)
|
private readonly void RecordStencilTestEnable(ExtExtendedDynamicState api, CommandBuffer commandBuffer)
|
||||||
{
|
{
|
||||||
api.CmdSetStencilTestEnable(commandBuffer, _stencilTestEnable);
|
api.CmdSetStencilTestEnable(commandBuffer, _stencilTestEnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RecordViewport(VulkanRenderer gd, CommandBuffer commandBuffer)
|
private void RecordViewport(VulkanRenderer gd, CommandBuffer commandBuffer)
|
||||||
{
|
{
|
||||||
if (ViewportsCount == 0)
|
if (ViewportsCount == 0)
|
||||||
|
@ -369,34 +389,39 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Viewports.AsSpan());
|
Viewports.AsSpan());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RecordCullMode(ExtExtendedDynamicState api, CommandBuffer commandBuffer)
|
private readonly void RecordCullMode(ExtExtendedDynamicState api, CommandBuffer commandBuffer)
|
||||||
{
|
{
|
||||||
api.CmdSetCullMode(commandBuffer, CullMode);
|
api.CmdSetCullMode(commandBuffer, CullMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RecordFrontFace(ExtExtendedDynamicState api, CommandBuffer commandBuffer)
|
private readonly void RecordFrontFace(ExtExtendedDynamicState api, CommandBuffer commandBuffer)
|
||||||
{
|
{
|
||||||
api.CmdSetFrontFace(commandBuffer, FrontFace);
|
api.CmdSetFrontFace(commandBuffer, FrontFace);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RecordDepthTestBool(ExtExtendedDynamicState api, CommandBuffer commandBuffer)
|
private readonly void RecordDepthTestBool(ExtExtendedDynamicState api, CommandBuffer commandBuffer)
|
||||||
{
|
{
|
||||||
api.CmdSetDepthTestEnable(commandBuffer, _depthtestEnable);
|
api.CmdSetDepthTestEnable(commandBuffer, _depthtestEnable);
|
||||||
api.CmdSetDepthWriteEnable(commandBuffer, _depthwriteEnable);
|
api.CmdSetDepthWriteEnable(commandBuffer, _depthwriteEnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RecordDepthTestCompareOp(ExtExtendedDynamicState api, CommandBuffer commandBuffer)
|
private readonly void RecordDepthTestCompareOp(ExtExtendedDynamicState api, CommandBuffer commandBuffer)
|
||||||
{
|
{
|
||||||
api.CmdSetDepthCompareOp(commandBuffer, _depthCompareOp);
|
api.CmdSetDepthCompareOp(commandBuffer, _depthCompareOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RecordRasterizationDiscard(VulkanRenderer gd, CommandBuffer commandBuffer)
|
private readonly void RecordRasterizationDiscard(VulkanRenderer gd, CommandBuffer commandBuffer)
|
||||||
{
|
{
|
||||||
gd.ExtendedDynamicState2Api.CmdSetRasterizerDiscardEnable(commandBuffer, _discard);
|
gd.ExtendedDynamicState2Api.CmdSetRasterizerDiscardEnable(commandBuffer, _discard);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RecordLineWidth(Vk api, CommandBuffer commandBuffer)
|
private readonly void RecordLogicOp(VulkanRenderer gd, CommandBuffer commandBuffer)
|
||||||
|
{
|
||||||
|
gd.ExtendedDynamicState2Api.CmdSetLogicOp(commandBuffer, _logicOp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly void RecordLineWidth(Vk api, CommandBuffer commandBuffer)
|
||||||
{
|
{
|
||||||
if (!OperatingSystem.IsMacOS())
|
if (!OperatingSystem.IsMacOS())
|
||||||
{
|
{
|
||||||
|
|
|
@ -404,7 +404,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
UpdateVertexAttributeDescriptions(gd);
|
UpdateVertexAttributeDescriptions(gd);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool supportsExtDynamicState = gd.Capabilities.SupportsExtendedDynamicState;
|
bool supportsExtDynamicState = gd.Capabilities.SupportsExtendedDynamicState;
|
||||||
bool supportsExtDynamicState2 = gd.Capabilities.SupportsExtendedDynamicState2;
|
bool supportsExtDynamicState2 = gd.Capabilities.SupportsExtendedDynamicState2;
|
||||||
|
|
||||||
|
@ -457,7 +457,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
primitiveRestartEnable = true;
|
primitiveRestartEnable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var inputAssemblyState = new PipelineInputAssemblyStateCreateInfo
|
var inputAssemblyState = new PipelineInputAssemblyStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineInputAssemblyStateCreateInfo,
|
SType = StructureType.PipelineInputAssemblyStateCreateInfo,
|
||||||
|
@ -494,12 +494,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
rasterizationState.DepthBiasEnable = DepthBiasEnable;
|
rasterizationState.DepthBiasEnable = DepthBiasEnable;
|
||||||
rasterizationState.RasterizerDiscardEnable = RasterizerDiscardEnable;
|
rasterizationState.RasterizerDiscardEnable = RasterizerDiscardEnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewportState = new PipelineViewportStateCreateInfo
|
var viewportState = new PipelineViewportStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineViewportStateCreateInfo,
|
SType = StructureType.PipelineViewportStateCreateInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!supportsExtDynamicState)
|
if (!supportsExtDynamicState)
|
||||||
{
|
{
|
||||||
viewportState.ViewportCount = ViewportsCount;
|
viewportState.ViewportCount = ViewportsCount;
|
||||||
|
@ -534,7 +534,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
MinDepthBounds = MinDepthBounds,
|
MinDepthBounds = MinDepthBounds,
|
||||||
MaxDepthBounds = MaxDepthBounds,
|
MaxDepthBounds = MaxDepthBounds,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!supportsExtDynamicState)
|
if (!supportsExtDynamicState)
|
||||||
{
|
{
|
||||||
var stencilFront = new StencilOpState(
|
var stencilFront = new StencilOpState(
|
||||||
|
@ -588,11 +588,15 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineColorBlendStateCreateInfo,
|
SType = StructureType.PipelineColorBlendStateCreateInfo,
|
||||||
LogicOpEnable = LogicOpEnable,
|
LogicOpEnable = LogicOpEnable,
|
||||||
LogicOp = LogicOp,
|
|
||||||
AttachmentCount = ColorBlendAttachmentStateCount,
|
AttachmentCount = ColorBlendAttachmentStateCount,
|
||||||
PAttachments = pColorBlendAttachmentState,
|
PAttachments = pColorBlendAttachmentState,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!(supportsExtDynamicState2 && gd.ExtendedLogicOp))
|
||||||
|
{
|
||||||
|
colorBlendState.LogicOp = LogicOp;
|
||||||
|
}
|
||||||
|
|
||||||
PipelineColorBlendAdvancedStateCreateInfoEXT colorBlendAdvancedState;
|
PipelineColorBlendAdvancedStateCreateInfoEXT colorBlendAdvancedState;
|
||||||
|
|
||||||
if (!AdvancedBlendSrcPreMultiplied ||
|
if (!AdvancedBlendSrcPreMultiplied ||
|
||||||
|
@ -609,9 +613,30 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
colorBlendState.PNext = &colorBlendAdvancedState;
|
colorBlendState.PNext = &colorBlendAdvancedState;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dynamicStatesCount = supportsExtDynamicState ? (isMoltenVk ? 18 : 19) : (isMoltenVk ? 7 : 8);
|
|
||||||
|
|
||||||
|
int baseDynamicStatesCount = 7;
|
||||||
|
int additionalDynamicStatesCount = 0;
|
||||||
|
|
||||||
|
if (!isMoltenVk)
|
||||||
|
{
|
||||||
|
baseDynamicStatesCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (supportsExtDynamicState)
|
||||||
|
{
|
||||||
|
additionalDynamicStatesCount += isMoltenVk ? 11 : 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (supportsExtDynamicState2)
|
||||||
|
{
|
||||||
|
additionalDynamicStatesCount += 2;
|
||||||
|
if (gd.ExtendedLogicOp)
|
||||||
|
{
|
||||||
|
additionalDynamicStatesCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int dynamicStatesCount = baseDynamicStatesCount + additionalDynamicStatesCount;
|
||||||
DynamicState* dynamicStates = stackalloc DynamicState[dynamicStatesCount];
|
DynamicState* dynamicStates = stackalloc DynamicState[dynamicStatesCount];
|
||||||
|
|
||||||
dynamicStates[0] = DynamicState.Viewport;
|
dynamicStates[0] = DynamicState.Viewport;
|
||||||
|
@ -621,33 +646,40 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
dynamicStates[4] = DynamicState.StencilWriteMask;
|
dynamicStates[4] = DynamicState.StencilWriteMask;
|
||||||
dynamicStates[5] = DynamicState.StencilReference;
|
dynamicStates[5] = DynamicState.StencilReference;
|
||||||
dynamicStates[6] = DynamicState.BlendConstants;
|
dynamicStates[6] = DynamicState.BlendConstants;
|
||||||
|
|
||||||
if(!isMoltenVk)
|
int currentIndex = 7;
|
||||||
|
|
||||||
|
if (!isMoltenVk)
|
||||||
{
|
{
|
||||||
dynamicStates[7] = DynamicState.LineWidth;
|
dynamicStates[currentIndex++] = DynamicState.LineWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (supportsExtDynamicState)
|
if (supportsExtDynamicState)
|
||||||
{
|
{
|
||||||
int index = (isMoltenVk ? 7 : 8);
|
if (!isMoltenVk)
|
||||||
if (!isMoltenVk) {
|
{
|
||||||
dynamicStates[index++] = DynamicState.VertexInputBindingStrideExt;
|
dynamicStates[currentIndex++] = DynamicState.VertexInputBindingStrideExt;
|
||||||
}
|
}
|
||||||
dynamicStates[index++] = DynamicState.CullModeExt;
|
dynamicStates[currentIndex++] = DynamicState.CullModeExt;
|
||||||
dynamicStates[index++] = DynamicState.FrontFaceExt;
|
dynamicStates[currentIndex++] = DynamicState.FrontFaceExt;
|
||||||
dynamicStates[index++] = DynamicState.DepthTestEnableExt;
|
dynamicStates[currentIndex++] = DynamicState.DepthTestEnableExt;
|
||||||
dynamicStates[index++] = DynamicState.DepthWriteEnableExt;
|
dynamicStates[currentIndex++] = DynamicState.DepthWriteEnableExt;
|
||||||
dynamicStates[index++] = DynamicState.DepthCompareOpExt;
|
dynamicStates[currentIndex++] = DynamicState.DepthCompareOpExt;
|
||||||
dynamicStates[index++] = DynamicState.StencilTestEnableExt;
|
dynamicStates[currentIndex++] = DynamicState.StencilTestEnableExt;
|
||||||
dynamicStates[index++] = DynamicState.ViewportWithCountExt;
|
dynamicStates[currentIndex++] = DynamicState.ViewportWithCountExt;
|
||||||
dynamicStates[index++] = DynamicState.ScissorWithCountExt;
|
dynamicStates[currentIndex++] = DynamicState.ScissorWithCountExt;
|
||||||
dynamicStates[index] = DynamicState.StencilOpExt;
|
dynamicStates[currentIndex++] = DynamicState.StencilOpExt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (supportsExtDynamicState2)
|
if (supportsExtDynamicState2)
|
||||||
{
|
{
|
||||||
dynamicStates[16] = DynamicState.DepthBiasEnableExt;
|
dynamicStates[currentIndex++] = DynamicState.DepthBiasEnableExt;
|
||||||
dynamicStates[17] = DynamicState.RasterizerDiscardEnableExt;
|
dynamicStates[currentIndex++] = DynamicState.RasterizerDiscardEnableExt;
|
||||||
|
|
||||||
|
if (gd.ExtendedLogicOp)
|
||||||
|
{
|
||||||
|
dynamicStates[currentIndex++] = DynamicState.LogicOpExt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo
|
var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo
|
||||||
|
|
|
@ -263,7 +263,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return InvalidIndex;
|
return InvalidIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static Device CreateDevice(Vk api, VulkanPhysicalDevice physicalDevice, uint queueFamilyIndex, uint queueCount)
|
internal static Device CreateDevice(Vk api, VulkanPhysicalDevice physicalDevice, uint queueFamilyIndex, uint queueCount, out bool extendedLogicOp)
|
||||||
{
|
{
|
||||||
if (queueCount > QueuesCount)
|
if (queueCount > QueuesCount)
|
||||||
{
|
{
|
||||||
|
@ -291,7 +291,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceFeatures2,
|
SType = StructureType.PhysicalDeviceFeatures2,
|
||||||
};
|
};
|
||||||
|
|
||||||
PhysicalDeviceVulkan11Features supportedFeaturesVk11 = new()
|
PhysicalDeviceVulkan11Features supportedFeaturesVk11 = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceVulkan11Features,
|
SType = StructureType.PhysicalDeviceVulkan11Features,
|
||||||
|
@ -310,7 +310,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
features2.PNext = &supportedFeaturesCustomBorderColor;
|
features2.PNext = &supportedFeaturesCustomBorderColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicalDeviceExtendedDynamicState2FeaturesEXT supportedFeaturesExtExtendedDynamicState2 = new()
|
PhysicalDeviceExtendedDynamicState2FeaturesEXT supportedFeaturesExtExtendedDynamicState2 = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceExtendedDynamicState2FeaturesExt,
|
SType = StructureType.PhysicalDeviceExtendedDynamicState2FeaturesExt,
|
||||||
|
@ -450,7 +450,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
};
|
};
|
||||||
|
|
||||||
pExtendedFeatures = &featuresExtendedDynamicState;
|
pExtendedFeatures = &featuresExtendedDynamicState;
|
||||||
|
|
||||||
var featuresExtendedDynamicState2 = new PhysicalDeviceExtendedDynamicState2FeaturesEXT()
|
var featuresExtendedDynamicState2 = new PhysicalDeviceExtendedDynamicState2FeaturesEXT()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceExtendedDynamicState2FeaturesExt,
|
SType = StructureType.PhysicalDeviceExtendedDynamicState2FeaturesExt,
|
||||||
|
@ -460,6 +460,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
ExtendedDynamicState2PatchControlPoints = supportedFeaturesExtExtendedDynamicState2.ExtendedDynamicState2PatchControlPoints,
|
ExtendedDynamicState2PatchControlPoints = supportedFeaturesExtExtendedDynamicState2.ExtendedDynamicState2PatchControlPoints,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extendedLogicOp = supportedFeaturesExtExtendedDynamicState2.ExtendedDynamicState2LogicOp;
|
||||||
|
|
||||||
pExtendedFeatures = &featuresExtendedDynamicState2;
|
pExtendedFeatures = &featuresExtendedDynamicState2;
|
||||||
|
|
||||||
var featuresVk11 = new PhysicalDeviceVulkan11Features
|
var featuresVk11 = new PhysicalDeviceVulkan11Features
|
||||||
|
|
|
@ -99,6 +99,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public bool PreferThreading => true;
|
public bool PreferThreading => true;
|
||||||
|
|
||||||
|
public bool ExtendedLogicOp;
|
||||||
|
|
||||||
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;
|
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;
|
||||||
|
|
||||||
public VulkanRenderer(Vk api, Func<Instance, Vk, SurfaceKHR> surfaceFunc, Func<string[]> requiredExtensionsFunc, string preferredGpuId)
|
public VulkanRenderer(Vk api, Func<Instance, Vk, SurfaceKHR> surfaceFunc, Func<string[]> requiredExtensionsFunc, string preferredGpuId)
|
||||||
|
@ -133,7 +135,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
ExtendedDynamicStateApi = extendedDynamicStateApi;
|
ExtendedDynamicStateApi = extendedDynamicStateApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Api.TryGetDeviceExtension(_instance.Instance, _device, out ExtExtendedDynamicState2 extendedDynamicState2Api))
|
if (Api.TryGetDeviceExtension(_instance.Instance, _device, out ExtExtendedDynamicState2 extendedDynamicState2Api))
|
||||||
{
|
{
|
||||||
ExtendedDynamicState2Api = extendedDynamicState2Api;
|
ExtendedDynamicState2Api = extendedDynamicState2Api;
|
||||||
|
@ -454,7 +456,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
var queueFamilyIndex = VulkanInitialization.FindSuitableQueueFamily(Api, _physicalDevice, _surface, out uint maxQueueCount);
|
var queueFamilyIndex = VulkanInitialization.FindSuitableQueueFamily(Api, _physicalDevice, _surface, out uint maxQueueCount);
|
||||||
|
|
||||||
_device = VulkanInitialization.CreateDevice(Api, _physicalDevice, queueFamilyIndex, maxQueueCount);
|
_device = VulkanInitialization.CreateDevice(Api, _physicalDevice, queueFamilyIndex, maxQueueCount, out bool extendedLogicOp);
|
||||||
|
|
||||||
|
ExtendedLogicOp = extendedLogicOp;
|
||||||
|
|
||||||
if (Api.TryGetDeviceExtension(_instance.Instance, _device, out KhrSwapchain swapchainApi))
|
if (Api.TryGetDeviceExtension(_instance.Instance, _device, out KhrSwapchain swapchainApi))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue