Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
dbe43c1719 | ||
|
f502cfaf62 |
@@ -68,6 +68,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
private bool _tfEnabled;
|
private bool _tfEnabled;
|
||||||
private bool _tfActive;
|
private bool _tfActive;
|
||||||
|
|
||||||
|
private PipelineColorBlendAttachmentState[] _storedBlend;
|
||||||
|
|
||||||
public ulong DrawCount { get; private set; }
|
public ulong DrawCount { get; private set; }
|
||||||
|
|
||||||
public unsafe PipelineBase(VulkanRenderer gd, Device device)
|
public unsafe PipelineBase(VulkanRenderer gd, Device device)
|
||||||
@@ -104,6 +106,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_newState.Initialize();
|
_newState.Initialize();
|
||||||
_newState.LineWidth = 1f;
|
_newState.LineWidth = 1f;
|
||||||
_newState.SamplesCount = 1;
|
_newState.SamplesCount = 1;
|
||||||
|
|
||||||
|
_storedBlend = new PipelineColorBlendAttachmentState[8];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
@@ -498,13 +502,28 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
ref var vkBlend = ref _newState.Internal.ColorBlendAttachmentState[index];
|
ref var vkBlend = ref _newState.Internal.ColorBlendAttachmentState[index];
|
||||||
|
|
||||||
vkBlend.BlendEnable = blend.Enable;
|
if (blend.Enable)
|
||||||
vkBlend.SrcColorBlendFactor = blend.ColorSrcFactor.Convert();
|
{
|
||||||
vkBlend.DstColorBlendFactor = blend.ColorDstFactor.Convert();
|
vkBlend.BlendEnable = blend.Enable;
|
||||||
vkBlend.ColorBlendOp = blend.ColorOp.Convert();
|
vkBlend.SrcColorBlendFactor = blend.ColorSrcFactor.Convert();
|
||||||
vkBlend.SrcAlphaBlendFactor = blend.AlphaSrcFactor.Convert();
|
vkBlend.DstColorBlendFactor = blend.ColorDstFactor.Convert();
|
||||||
vkBlend.DstAlphaBlendFactor = blend.AlphaDstFactor.Convert();
|
vkBlend.ColorBlendOp = blend.ColorOp.Convert();
|
||||||
vkBlend.AlphaBlendOp = blend.AlphaOp.Convert();
|
vkBlend.SrcAlphaBlendFactor = blend.AlphaSrcFactor.Convert();
|
||||||
|
vkBlend.DstAlphaBlendFactor = blend.AlphaDstFactor.Convert();
|
||||||
|
vkBlend.AlphaBlendOp = blend.AlphaOp.Convert();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vkBlend = new PipelineColorBlendAttachmentState(
|
||||||
|
colorWriteMask: vkBlend.ColorWriteMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vkBlend.ColorWriteMask == 0)
|
||||||
|
{
|
||||||
|
_storedBlend[index] = vkBlend;
|
||||||
|
|
||||||
|
vkBlend = new PipelineColorBlendAttachmentState();
|
||||||
|
}
|
||||||
|
|
||||||
_newState.BlendConstantR = blend.BlendConstant.Red;
|
_newState.BlendConstantR = blend.BlendConstant.Red;
|
||||||
_newState.BlendConstantG = blend.BlendConstant.Green;
|
_newState.BlendConstantG = blend.BlendConstant.Green;
|
||||||
@@ -669,8 +688,25 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
ref var vkBlend = ref _newState.Internal.ColorBlendAttachmentState[i];
|
ref var vkBlend = ref _newState.Internal.ColorBlendAttachmentState[i];
|
||||||
|
var newMask = (ColorComponentFlags)componentMask[i];
|
||||||
|
|
||||||
vkBlend.ColorWriteMask = (ColorComponentFlags)componentMask[i];
|
// When color write mask is 0, remove all blend state to help the pipeline cache.
|
||||||
|
// Restore it when the mask becomes non-zero.
|
||||||
|
if (vkBlend.ColorWriteMask != newMask)
|
||||||
|
{
|
||||||
|
if (newMask == 0)
|
||||||
|
{
|
||||||
|
_storedBlend[i] = vkBlend;
|
||||||
|
|
||||||
|
vkBlend = new PipelineColorBlendAttachmentState();
|
||||||
|
}
|
||||||
|
else if (vkBlend.ColorWriteMask == 0)
|
||||||
|
{
|
||||||
|
vkBlend = _storedBlend[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vkBlend.ColorWriteMask = newMask;
|
||||||
|
|
||||||
if (componentMask[i] != 0)
|
if (componentMask[i] != 0)
|
||||||
{
|
{
|
||||||
|
@@ -257,15 +257,23 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
var blend = state.BlendDescriptors[i];
|
var blend = state.BlendDescriptors[i];
|
||||||
|
|
||||||
pipeline.Internal.ColorBlendAttachmentState[i] = new PipelineColorBlendAttachmentState(
|
if (blend.Enable && state.ColorWriteMask[i] != 0)
|
||||||
blend.Enable,
|
{
|
||||||
blend.ColorSrcFactor.Convert(),
|
pipeline.Internal.ColorBlendAttachmentState[i] = new PipelineColorBlendAttachmentState(
|
||||||
blend.ColorDstFactor.Convert(),
|
blend.Enable,
|
||||||
blend.ColorOp.Convert(),
|
blend.ColorSrcFactor.Convert(),
|
||||||
blend.AlphaSrcFactor.Convert(),
|
blend.ColorDstFactor.Convert(),
|
||||||
blend.AlphaDstFactor.Convert(),
|
blend.ColorOp.Convert(),
|
||||||
blend.AlphaOp.Convert(),
|
blend.AlphaSrcFactor.Convert(),
|
||||||
(ColorComponentFlags)state.ColorWriteMask[i]);
|
blend.AlphaDstFactor.Convert(),
|
||||||
|
blend.AlphaOp.Convert(),
|
||||||
|
(ColorComponentFlags)state.ColorWriteMask[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pipeline.Internal.ColorBlendAttachmentState[i] = new PipelineColorBlendAttachmentState(
|
||||||
|
colorWriteMask: (ColorComponentFlags)state.ColorWriteMask[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxAttachmentIndex = 0;
|
int maxAttachmentIndex = 0;
|
||||||
|
@@ -181,7 +181,11 @@ namespace Ryujinx.HLE.HOS.Services.Ssl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGetCertificates(ReadOnlySpan<CaCertificateId> ids, out CertStoreEntry[] entries)
|
public bool TryGetCertificates(
|
||||||
|
ReadOnlySpan<CaCertificateId> ids,
|
||||||
|
out CertStoreEntry[] entries,
|
||||||
|
out bool hasAllCertificates,
|
||||||
|
out int requiredSize)
|
||||||
{
|
{
|
||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
@@ -190,7 +194,8 @@ namespace Ryujinx.HLE.HOS.Services.Ssl
|
|||||||
throw new InvalidSystemResourceException(CertStoreTitleMissingErrorMessage);
|
throw new InvalidSystemResourceException(CertStoreTitleMissingErrorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasAllCertificates = false;
|
requiredSize = 0;
|
||||||
|
hasAllCertificates = false;
|
||||||
|
|
||||||
foreach (CaCertificateId id in ids)
|
foreach (CaCertificateId id in ids)
|
||||||
{
|
{
|
||||||
@@ -205,12 +210,14 @@ namespace Ryujinx.HLE.HOS.Services.Ssl
|
|||||||
if (hasAllCertificates)
|
if (hasAllCertificates)
|
||||||
{
|
{
|
||||||
entries = new CertStoreEntry[_certificates.Count];
|
entries = new CertStoreEntry[_certificates.Count];
|
||||||
|
requiredSize = (_certificates.Count + 1) * Unsafe.SizeOf<BuiltInCertificateInfo>();
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
foreach (CertStoreEntry entry in _certificates.Values)
|
foreach (CertStoreEntry entry in _certificates.Values)
|
||||||
{
|
{
|
||||||
entries[i++] = entry;
|
entries[i++] = entry;
|
||||||
|
requiredSize += (entry.Data.Length + 3) & ~3;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -218,6 +225,7 @@ namespace Ryujinx.HLE.HOS.Services.Ssl
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
entries = new CertStoreEntry[ids.Length];
|
entries = new CertStoreEntry[ids.Length];
|
||||||
|
requiredSize = ids.Length * Unsafe.SizeOf<BuiltInCertificateInfo>();
|
||||||
|
|
||||||
for (int i = 0; i < ids.Length; i++)
|
for (int i = 0; i < ids.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -227,6 +235,7 @@ namespace Ryujinx.HLE.HOS.Services.Ssl
|
|||||||
}
|
}
|
||||||
|
|
||||||
entries[i] = entry;
|
entries[i] = entry;
|
||||||
|
requiredSize += (entry.Data.Length + 3) & ~3;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@@ -29,42 +29,40 @@ namespace Ryujinx.HLE.HOS.Services.Ssl
|
|||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private uint ComputeCertificateBufferSizeRequired(ReadOnlySpan<BuiltInCertificateManager.CertStoreEntry> entries)
|
|
||||||
{
|
|
||||||
uint totalSize = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < entries.Length; i++)
|
|
||||||
{
|
|
||||||
totalSize += (uint)Unsafe.SizeOf<BuiltInCertificateInfo>();
|
|
||||||
totalSize += (uint)entries[i].Data.Length;
|
|
||||||
}
|
|
||||||
|
|
||||||
return totalSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
[CommandHipc(2)]
|
[CommandHipc(2)]
|
||||||
// GetCertificates(buffer<CaCertificateId, 5> ids) -> (u32 certificates_count, buffer<bytes, 6> certificates)
|
// GetCertificates(buffer<CaCertificateId, 5> ids) -> (u32 certificates_count, buffer<bytes, 6> certificates)
|
||||||
public ResultCode GetCertificates(ServiceCtx context)
|
public ResultCode GetCertificates(ServiceCtx context)
|
||||||
{
|
{
|
||||||
ReadOnlySpan<CaCertificateId> ids = MemoryMarshal.Cast<byte, CaCertificateId>(context.Memory.GetSpan(context.Request.SendBuff[0].Position, (int)context.Request.SendBuff[0].Size));
|
ReadOnlySpan<CaCertificateId> ids = MemoryMarshal.Cast<byte, CaCertificateId>(context.Memory.GetSpan(context.Request.SendBuff[0].Position, (int)context.Request.SendBuff[0].Size));
|
||||||
|
|
||||||
if (!BuiltInCertificateManager.Instance.TryGetCertificates(ids, out BuiltInCertificateManager.CertStoreEntry[] entries))
|
if (!BuiltInCertificateManager.Instance.TryGetCertificates(
|
||||||
|
ids,
|
||||||
|
out BuiltInCertificateManager.CertStoreEntry[] entries,
|
||||||
|
out bool hasAllCertificates,
|
||||||
|
out int requiredSize))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ComputeCertificateBufferSizeRequired(entries) > context.Request.ReceiveBuff[0].Size)
|
if ((uint)requiredSize > (uint)context.Request.ReceiveBuff[0].Size)
|
||||||
{
|
{
|
||||||
return ResultCode.InvalidCertBufSize;
|
return ResultCode.InvalidCertBufSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int infosCount = entries.Length;
|
||||||
|
|
||||||
|
if (hasAllCertificates)
|
||||||
|
{
|
||||||
|
infosCount++;
|
||||||
|
}
|
||||||
|
|
||||||
using (WritableRegion region = context.Memory.GetWritableRegion(context.Request.ReceiveBuff[0].Position, (int)context.Request.ReceiveBuff[0].Size))
|
using (WritableRegion region = context.Memory.GetWritableRegion(context.Request.ReceiveBuff[0].Position, (int)context.Request.ReceiveBuff[0].Size))
|
||||||
{
|
{
|
||||||
Span<byte> rawData = region.Memory.Span;
|
Span<byte> rawData = region.Memory.Span;
|
||||||
Span<BuiltInCertificateInfo> infos = MemoryMarshal.Cast<byte, BuiltInCertificateInfo>(rawData)[..entries.Length];
|
Span<BuiltInCertificateInfo> infos = MemoryMarshal.Cast<byte, BuiltInCertificateInfo>(rawData)[..infosCount];
|
||||||
Span<byte> certificatesData = rawData[(Unsafe.SizeOf<BuiltInCertificateInfo>() * entries.Length)..];
|
Span<byte> certificatesData = rawData[(Unsafe.SizeOf<BuiltInCertificateInfo>() * infosCount)..];
|
||||||
|
|
||||||
for (int i = 0; i < infos.Length; i++)
|
for (int i = 0; i < entries.Length; i++)
|
||||||
{
|
{
|
||||||
entries[i].Data.CopyTo(certificatesData);
|
entries[i].Data.CopyTo(certificatesData);
|
||||||
|
|
||||||
@@ -78,6 +76,17 @@ namespace Ryujinx.HLE.HOS.Services.Ssl
|
|||||||
|
|
||||||
certificatesData = certificatesData[entries[i].Data.Length..];
|
certificatesData = certificatesData[entries[i].Data.Length..];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasAllCertificates)
|
||||||
|
{
|
||||||
|
infos[entries.Length] = new BuiltInCertificateInfo
|
||||||
|
{
|
||||||
|
Id = CaCertificateId.All,
|
||||||
|
Status = TrustedCertStatus.Invalid,
|
||||||
|
CertificateDataSize = 0,
|
||||||
|
CertificateDataOffset = 0
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context.ResponseData.Write(entries.Length);
|
context.ResponseData.Write(entries.Length);
|
||||||
@@ -91,12 +100,12 @@ namespace Ryujinx.HLE.HOS.Services.Ssl
|
|||||||
{
|
{
|
||||||
ReadOnlySpan<CaCertificateId> ids = MemoryMarshal.Cast<byte, CaCertificateId>(context.Memory.GetSpan(context.Request.SendBuff[0].Position, (int)context.Request.SendBuff[0].Size));
|
ReadOnlySpan<CaCertificateId> ids = MemoryMarshal.Cast<byte, CaCertificateId>(context.Memory.GetSpan(context.Request.SendBuff[0].Position, (int)context.Request.SendBuff[0].Size));
|
||||||
|
|
||||||
if (!BuiltInCertificateManager.Instance.TryGetCertificates(ids, out BuiltInCertificateManager.CertStoreEntry[] entries))
|
if (!BuiltInCertificateManager.Instance.TryGetCertificates(ids, out _, out _, out int requiredSize))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
context.ResponseData.Write(ComputeCertificateBufferSizeRequired(entries));
|
context.ResponseData.Write(requiredSize);
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user