Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
b5032b3c91 | ||
|
f0a3dff136 | ||
|
f659dcb9d8 | ||
|
a34fb0e939 | ||
|
21ce8a9b80 | ||
|
9ecbee8032 | ||
|
80519af67d | ||
|
26e30faff3 | ||
|
0992310b76 | ||
|
009c1101d2 | ||
|
ba95ee54ab | ||
|
4ce4299ca2 |
11
.github/workflows/release.yml
vendored
11
.github/workflows/release.yml
vendored
@@ -112,6 +112,17 @@ jobs:
|
||||
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
|
||||
- name: Create tag
|
||||
uses: actions/github-script@v5
|
||||
with:
|
||||
script: |
|
||||
github.rest.git.createRef({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
ref: 'refs/tags/${{ steps.version_info.outputs.build_version }}',
|
||||
sha: context.sha
|
||||
})
|
||||
|
||||
flatpak_release:
|
||||
uses: ./.github/workflows/flatpak.yml
|
||||
needs: release
|
||||
|
@@ -34,6 +34,12 @@ namespace ARMeilleure.CodeGen.X86
|
||||
|
||||
private static uint GetXcr0Eax()
|
||||
{
|
||||
if (!FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Xsave))
|
||||
{
|
||||
// XSAVE feature required for xgetbv
|
||||
return 0;
|
||||
}
|
||||
|
||||
ReadOnlySpan<byte> asmGetXcr0 = new byte[]
|
||||
{
|
||||
0x31, 0xc9, // xor ecx, ecx
|
||||
@@ -70,6 +76,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||
Sse42 = 1 << 20,
|
||||
Popcnt = 1 << 23,
|
||||
Aes = 1 << 25,
|
||||
Xsave = 1 << 26,
|
||||
Osxsave = 1 << 27,
|
||||
Avx = 1 << 28,
|
||||
F16c = 1 << 29
|
||||
@@ -118,9 +125,9 @@ namespace ARMeilleure.CodeGen.X86
|
||||
public static bool SupportsSse42 => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Sse42);
|
||||
public static bool SupportsPopcnt => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Popcnt);
|
||||
public static bool SupportsAesni => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Aes);
|
||||
public static bool SupportsAvx => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Avx | FeatureFlags1Ecx.Osxsave) && Xcr0InfoEax.HasFlag(Xcr0FlagsEax.Sse | Xcr0FlagsEax.YmmHi128);
|
||||
public static bool SupportsAvx => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Avx | FeatureFlags1Ecx.Xsave | FeatureFlags1Ecx.Osxsave) && Xcr0InfoEax.HasFlag(Xcr0FlagsEax.Sse | Xcr0FlagsEax.YmmHi128);
|
||||
public static bool SupportsAvx2 => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Avx2) && SupportsAvx;
|
||||
public static bool SupportsAvx512F => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Avx512f) && FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Osxsave)
|
||||
public static bool SupportsAvx512F => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Avx512f) && FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Xsave | FeatureFlags1Ecx.Osxsave)
|
||||
&& Xcr0InfoEax.HasFlag(Xcr0FlagsEax.Sse | Xcr0FlagsEax.YmmHi128 | Xcr0FlagsEax.Opmask | Xcr0FlagsEax.ZmmHi256 | Xcr0FlagsEax.Hi16Zmm);
|
||||
public static bool SupportsAvx512Vl => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Avx512vl) && SupportsAvx512F;
|
||||
public static bool SupportsAvx512Bw => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Avx512bw) && SupportsAvx512F;
|
||||
|
@@ -34,7 +34,7 @@
|
||||
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build13" />
|
||||
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
||||
<PackageVersion Include="Ryujinx.GtkSharp" Version="3.24.24.59-ryujinx" />
|
||||
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.26.1-build23" />
|
||||
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.26.3-build25" />
|
||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
||||
<PackageVersion Include="Silk.NET.Vulkan" Version="2.16.0" />
|
||||
|
@@ -180,7 +180,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
|
||||
int firstInstance = (int)_state.State.FirstInstance;
|
||||
|
||||
int inlineIndexCount = _drawState.IbStreamer.GetAndResetInlineIndexCount();
|
||||
int inlineIndexCount = _drawState.IbStreamer.GetAndResetInlineIndexCount(_context.Renderer);
|
||||
|
||||
if (inlineIndexCount != 0)
|
||||
{
|
||||
@@ -670,7 +670,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
{
|
||||
if (indexedInline)
|
||||
{
|
||||
int inlineIndexCount = _drawState.IbStreamer.GetAndResetInlineIndexCount();
|
||||
int inlineIndexCount = _drawState.IbStreamer.GetAndResetInlineIndexCount(_context.Renderer);
|
||||
BufferRange br = new BufferRange(_drawState.IbStreamer.GetInlineIndexBuffer(), 0, inlineIndexCount * 4);
|
||||
|
||||
_channel.BufferManager.SetIndexBuffer(br, IndexType.UInt);
|
||||
|
@@ -11,9 +11,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct IbStreamer
|
||||
{
|
||||
private const int BufferCapacity = 256; // Must be a power of 2.
|
||||
|
||||
private BufferHandle _inlineIndexBuffer;
|
||||
private int _inlineIndexBufferSize;
|
||||
private int _inlineIndexCount;
|
||||
private uint[] _buffer;
|
||||
private int _bufferOffset;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if any index buffer data has been pushed.
|
||||
@@ -38,9 +42,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// Gets the number of elements on the current inline index buffer,
|
||||
/// while also reseting it to zero for the next draw.
|
||||
/// </summary>
|
||||
/// <param name="renderer">Host renderer</param>
|
||||
/// <returns>Inline index bufffer count</returns>
|
||||
public int GetAndResetInlineIndexCount()
|
||||
public int GetAndResetInlineIndexCount(IRenderer renderer)
|
||||
{
|
||||
UpdateRemaining(renderer);
|
||||
int temp = _inlineIndexCount;
|
||||
_inlineIndexCount = 0;
|
||||
return temp;
|
||||
@@ -58,16 +64,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
byte i2 = (byte)(argument >> 16);
|
||||
byte i3 = (byte)(argument >> 24);
|
||||
|
||||
Span<uint> data = stackalloc uint[4];
|
||||
int offset = _inlineIndexCount;
|
||||
|
||||
data[0] = i0;
|
||||
data[1] = i1;
|
||||
data[2] = i2;
|
||||
data[3] = i3;
|
||||
|
||||
int offset = _inlineIndexCount * 4;
|
||||
|
||||
renderer.SetBufferData(GetInlineIndexBuffer(renderer, offset), offset, MemoryMarshal.Cast<uint, byte>(data));
|
||||
PushData(renderer, offset, i0);
|
||||
PushData(renderer, offset + 1, i1);
|
||||
PushData(renderer, offset + 2, i2);
|
||||
PushData(renderer, offset + 3, i3);
|
||||
|
||||
_inlineIndexCount += 4;
|
||||
}
|
||||
@@ -82,14 +84,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
ushort i0 = (ushort)argument;
|
||||
ushort i1 = (ushort)(argument >> 16);
|
||||
|
||||
Span<uint> data = stackalloc uint[2];
|
||||
int offset = _inlineIndexCount;
|
||||
|
||||
data[0] = i0;
|
||||
data[1] = i1;
|
||||
|
||||
int offset = _inlineIndexCount * 4;
|
||||
|
||||
renderer.SetBufferData(GetInlineIndexBuffer(renderer, offset), offset, MemoryMarshal.Cast<uint, byte>(data));
|
||||
PushData(renderer, offset, i0);
|
||||
PushData(renderer, offset + 1, i1);
|
||||
|
||||
_inlineIndexCount += 2;
|
||||
}
|
||||
@@ -103,13 +101,61 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
{
|
||||
uint i0 = (uint)argument;
|
||||
|
||||
Span<uint> data = stackalloc uint[1];
|
||||
int offset = _inlineIndexCount++;
|
||||
|
||||
data[0] = i0;
|
||||
PushData(renderer, offset, i0);
|
||||
}
|
||||
|
||||
int offset = _inlineIndexCount++ * 4;
|
||||
/// <summary>
|
||||
/// Pushes a 32-bit value to the index buffer.
|
||||
/// </summary>
|
||||
/// <param name="renderer">Host renderer</param>
|
||||
/// <param name="offset">Offset where the data should be written, in 32-bit words</param>
|
||||
/// <param name="value">Index value to be written</param>
|
||||
private void PushData(IRenderer renderer, int offset, uint value)
|
||||
{
|
||||
if (_buffer == null)
|
||||
{
|
||||
_buffer = new uint[BufferCapacity];
|
||||
}
|
||||
|
||||
renderer.SetBufferData(GetInlineIndexBuffer(renderer, offset), offset, MemoryMarshal.Cast<uint, byte>(data));
|
||||
// We upload data in chunks.
|
||||
// If we are at the start of a chunk, then the buffer might be full,
|
||||
// in that case we need to submit any existing data before overwriting the buffer.
|
||||
int subOffset = offset & (BufferCapacity - 1);
|
||||
|
||||
if (subOffset == 0 && offset != 0)
|
||||
{
|
||||
int baseOffset = (offset - BufferCapacity) * sizeof(uint);
|
||||
BufferHandle buffer = GetInlineIndexBuffer(renderer, baseOffset, BufferCapacity * sizeof(uint));
|
||||
renderer.SetBufferData(buffer, baseOffset, MemoryMarshal.Cast<uint, byte>(_buffer));
|
||||
}
|
||||
|
||||
_buffer[subOffset] = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes sure that any pending data is submitted to the GPU before the index buffer is used.
|
||||
/// </summary>
|
||||
/// <param name="renderer">Host renderer</param>
|
||||
private void UpdateRemaining(IRenderer renderer)
|
||||
{
|
||||
int offset = _inlineIndexCount;
|
||||
if (offset == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int count = offset & (BufferCapacity - 1);
|
||||
if (count == 0)
|
||||
{
|
||||
count = BufferCapacity;
|
||||
}
|
||||
|
||||
int baseOffset = (offset - count) * sizeof(uint);
|
||||
int length = count * sizeof(uint);
|
||||
BufferHandle buffer = GetInlineIndexBuffer(renderer, baseOffset, length);
|
||||
renderer.SetBufferData(buffer, baseOffset, MemoryMarshal.Cast<uint, byte>(_buffer).Slice(0, length));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -117,12 +163,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
/// <param name="renderer">Host renderer</param>
|
||||
/// <param name="offset">Offset where the data will be written</param>
|
||||
/// <param name="length">Number of bytes that will be written</param>
|
||||
/// <returns>Buffer handle</returns>
|
||||
private BufferHandle GetInlineIndexBuffer(IRenderer renderer, int offset)
|
||||
private BufferHandle GetInlineIndexBuffer(IRenderer renderer, int offset, int length)
|
||||
{
|
||||
// Calculate a reasonable size for the buffer that can fit all the data,
|
||||
// and that also won't require frequent resizes if we need to push more data.
|
||||
int size = BitUtils.AlignUp(offset + 0x10, 0x200);
|
||||
int size = BitUtils.AlignUp(offset + length + 0x10, 0x200);
|
||||
|
||||
if (_inlineIndexBuffer == BufferHandle.Null)
|
||||
{
|
||||
|
@@ -130,6 +130,10 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
return ref descriptor;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
texture.SynchronizeMemory();
|
||||
}
|
||||
|
||||
Items[id] = texture;
|
||||
|
||||
@@ -233,7 +237,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queues a request to update a texture's mapping.
|
||||
/// Queues a request to update a texture's mapping.
|
||||
/// Mapping is updated later to avoid deleting the texture if it is still sparsely mapped.
|
||||
/// </summary>
|
||||
/// <param name="texture">Texture with potential mapping change</param>
|
||||
|
@@ -236,7 +236,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
else if (texture is TextureView view)
|
||||
{
|
||||
view.Storage.InsertBarrier(cbs, AccessFlags.ShaderReadBit, stage.ConvertToPipelineStageFlags());
|
||||
view.Storage.InsertWriteToReadBarrier(cbs, AccessFlags.ShaderReadBit, stage.ConvertToPipelineStageFlags());
|
||||
|
||||
_textureRefs[binding] = view.GetImageView();
|
||||
_samplerRefs[binding] = ((SamplerHolder)sampler)?.GetSampler();
|
||||
|
@@ -322,7 +322,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
GAL.Format.S8Uint => ImageAspectFlags.StencilBit,
|
||||
GAL.Format.D24UnormS8Uint or
|
||||
GAL.Format.D32FloatS8Uint or
|
||||
GAL.Format.S8UintD24Unorm => ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit,
|
||||
GAL.Format.S8UintD24Unorm => ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit,
|
||||
_ => ImageAspectFlags.ColorBit
|
||||
};
|
||||
}
|
||||
|
@@ -218,5 +218,23 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
AccessFlags.DepthStencilAttachmentWriteBit,
|
||||
PipelineStageFlags.ColorAttachmentOutputBit);
|
||||
}
|
||||
|
||||
public void InsertClearBarrier(CommandBufferScoped cbs, int index)
|
||||
{
|
||||
if (_colors != null)
|
||||
{
|
||||
int realIndex = Array.IndexOf(AttachmentIndices, index);
|
||||
|
||||
if (realIndex != -1)
|
||||
{
|
||||
_colors[realIndex].Storage?.InsertReadToWriteBarrier(cbs, AccessFlags.ColorAttachmentWriteBit, PipelineStageFlags.ColorAttachmentOutputBit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void InsertClearBarrierDS(CommandBufferScoped cbs)
|
||||
{
|
||||
_depthStencil?.Storage?.InsertReadToWriteBarrier(cbs, AccessFlags.DepthStencilAttachmentWriteBit, PipelineStageFlags.EarlyFragmentTestsBit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -226,6 +226,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
var attachment = new ClearAttachment(ImageAspectFlags.ColorBit, (uint)index, clearValue);
|
||||
var clearRect = FramebufferParams.GetClearRect(ClearScissor, layer, layerCount);
|
||||
|
||||
FramebufferParams.InsertClearBarrier(Cbs, index);
|
||||
|
||||
Gd.Api.CmdClearAttachments(CommandBuffer, 1, &attachment, 1, &clearRect);
|
||||
}
|
||||
|
||||
@@ -256,6 +258,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
var attachment = new ClearAttachment(flags, 0, clearValue);
|
||||
var clearRect = FramebufferParams.GetClearRect(ClearScissor, layer, layerCount);
|
||||
|
||||
FramebufferParams.InsertClearBarrierDS(Cbs);
|
||||
|
||||
Gd.Api.CmdClearAttachments(CommandBuffer, 1, &attachment, 1, &clearRect);
|
||||
}
|
||||
|
||||
|
@@ -46,6 +46,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
private AccessFlags _lastModificationAccess;
|
||||
private PipelineStageFlags _lastModificationStage;
|
||||
private AccessFlags _lastReadAccess;
|
||||
private PipelineStageFlags _lastReadStage;
|
||||
|
||||
private int _viewsCount;
|
||||
private ulong _size;
|
||||
@@ -440,31 +442,39 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_lastModificationStage = stage;
|
||||
}
|
||||
|
||||
public void InsertBarrier(CommandBufferScoped cbs, AccessFlags dstAccessFlags, PipelineStageFlags dstStageFlags)
|
||||
public void InsertReadToWriteBarrier(CommandBufferScoped cbs, AccessFlags dstAccessFlags, PipelineStageFlags dstStageFlags)
|
||||
{
|
||||
if (_lastReadAccess != AccessFlags.NoneKhr)
|
||||
{
|
||||
ImageAspectFlags aspectFlags = Info.Format.ConvertAspectFlags();
|
||||
|
||||
TextureView.InsertImageBarrier(
|
||||
_gd.Api,
|
||||
cbs.CommandBuffer,
|
||||
_imageAuto.Get(cbs).Value,
|
||||
_lastReadAccess,
|
||||
dstAccessFlags,
|
||||
_lastReadStage,
|
||||
dstStageFlags,
|
||||
aspectFlags,
|
||||
0,
|
||||
0,
|
||||
_info.GetLayers(),
|
||||
_info.Levels);
|
||||
|
||||
_lastReadAccess = AccessFlags.NoneKhr;
|
||||
_lastReadStage = PipelineStageFlags.None;
|
||||
}
|
||||
}
|
||||
|
||||
public void InsertWriteToReadBarrier(CommandBufferScoped cbs, AccessFlags dstAccessFlags, PipelineStageFlags dstStageFlags)
|
||||
{
|
||||
_lastReadAccess |= dstAccessFlags;
|
||||
_lastReadStage |= dstStageFlags;
|
||||
|
||||
if (_lastModificationAccess != AccessFlags.NoneKhr)
|
||||
{
|
||||
ImageAspectFlags aspectFlags;
|
||||
|
||||
if (_info.Format.IsDepthOrStencil())
|
||||
{
|
||||
if (_info.Format == GAL.Format.S8Uint)
|
||||
{
|
||||
aspectFlags = ImageAspectFlags.StencilBit;
|
||||
}
|
||||
else if (_info.Format == GAL.Format.D16Unorm || _info.Format == GAL.Format.D32Float)
|
||||
{
|
||||
aspectFlags = ImageAspectFlags.DepthBit;
|
||||
}
|
||||
else
|
||||
{
|
||||
aspectFlags = ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
aspectFlags = ImageAspectFlags.ColorBit;
|
||||
}
|
||||
ImageAspectFlags aspectFlags = Info.Format.ConvertAspectFlags();
|
||||
|
||||
TextureView.InsertImageBarrier(
|
||||
_gd.Api,
|
||||
|
@@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private const string AppName = "Ryujinx.Graphics.Vulkan";
|
||||
private const int QueuesCount = 2;
|
||||
|
||||
public static string[] DesirableExtensions { get; } = new string[]
|
||||
private static readonly string[] _desirableExtensions = new string[]
|
||||
{
|
||||
ExtConditionalRendering.ExtensionName,
|
||||
ExtExtendedDynamicState.ExtensionName,
|
||||
@@ -42,7 +42,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
"VK_KHR_portability_subset", // By spec, we should enable this if present.
|
||||
};
|
||||
|
||||
public static string[] RequiredExtensions { get; } = new string[]
|
||||
private static readonly string[] _requiredExtensions = new string[]
|
||||
{
|
||||
KhrSwapchain.ExtensionName
|
||||
};
|
||||
@@ -337,14 +337,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
string extensionName = Marshal.PtrToStringAnsi((IntPtr)pExtensionProperties[i].ExtensionName);
|
||||
|
||||
if (RequiredExtensions.Contains(extensionName))
|
||||
if (_requiredExtensions.Contains(extensionName))
|
||||
{
|
||||
extensionMatches++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return extensionMatches == RequiredExtensions.Length && FindSuitableQueueFamily(api, physicalDevice, surface, out _) != InvalidIndex;
|
||||
return extensionMatches == _requiredExtensions.Length && FindSuitableQueueFamily(api, physicalDevice, surface, out _) != InvalidIndex;
|
||||
}
|
||||
|
||||
internal static uint FindSuitableQueueFamily(Vk api, PhysicalDevice physicalDevice, SurfaceKHR surface, out uint queueCount)
|
||||
@@ -626,7 +626,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
pExtendedFeatures = &featuresCustomBorderColor;
|
||||
}
|
||||
|
||||
var enabledExtensions = RequiredExtensions.Union(DesirableExtensions.Intersect(supportedExtensions)).ToArray();
|
||||
var enabledExtensions = _requiredExtensions.Union(_desirableExtensions.Intersect(supportedExtensions)).ToArray();
|
||||
|
||||
IntPtr* ppEnabledExtensions = stackalloc IntPtr[enabledExtensions.Length];
|
||||
|
||||
@@ -672,11 +672,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return extensionProperties.Select(x => Marshal.PtrToStringAnsi((IntPtr)x.ExtensionName)).ToArray();
|
||||
}
|
||||
|
||||
internal static CommandBufferPool CreateCommandBufferPool(Vk api, Device device, Queue queue, object queueLock, uint queueFamilyIndex)
|
||||
{
|
||||
return new CommandBufferPool(api, device, queue, queueLock, queueFamilyIndex);
|
||||
}
|
||||
|
||||
internal unsafe static void CreateDebugMessenger(
|
||||
Vk api,
|
||||
GraphicsDebugLevel logLevel,
|
||||
|
@@ -168,7 +168,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
SType = StructureType.PhysicalDeviceSubgroupSizeControlPropertiesExt
|
||||
};
|
||||
|
||||
if (Capabilities.SupportsSubgroupSizeControl)
|
||||
bool supportsSubgroupSizeControl = supportedExtensions.Contains("VK_EXT_subgroup_size_control");
|
||||
|
||||
if (supportsSubgroupSizeControl)
|
||||
{
|
||||
properties2.PNext = &propertiesSubgroupSizeControl;
|
||||
}
|
||||
@@ -292,7 +294,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
supportedExtensions.Contains(KhrDrawIndirectCount.ExtensionName),
|
||||
supportedExtensions.Contains("VK_EXT_fragment_shader_interlock"),
|
||||
supportedExtensions.Contains("VK_NV_geometry_shader_passthrough"),
|
||||
supportedExtensions.Contains("VK_EXT_subgroup_size_control"),
|
||||
supportsSubgroupSizeControl,
|
||||
featuresShaderInt8.ShaderInt8,
|
||||
supportedExtensions.Contains("VK_EXT_shader_stencil_export"),
|
||||
supportedExtensions.Contains(ExtConditionalRendering.ExtensionName),
|
||||
@@ -318,7 +320,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
MemoryAllocator = new MemoryAllocator(Api, _physicalDevice, _device, properties.Limits.MaxMemoryAllocationCount);
|
||||
|
||||
CommandBufferPool = VulkanInitialization.CreateCommandBufferPool(Api, _device, Queue, QueueLock, queueFamilyIndex);
|
||||
CommandBufferPool = new CommandBufferPool(Api, _device, Queue, QueueLock, queueFamilyIndex);
|
||||
|
||||
DescriptorSetManager = new DescriptorSetManager(_device);
|
||||
|
||||
|
@@ -14,6 +14,9 @@ namespace Ryujinx.HLE.HOS.Services.Nim
|
||||
// CreateServerInterface(pid, handle<unknown>, u64) -> object<nn::ec::IShopServiceAccessServer>
|
||||
public ResultCode CreateServerInterface(ServiceCtx context)
|
||||
{
|
||||
// Close transfer memory immediately as we don't use it.
|
||||
context.Device.System.KernelContext.Syscall.CloseHandle(context.Request.HandleDesc.ToCopy[0]);
|
||||
|
||||
MakeObject(context, new IShopServiceAccessServer());
|
||||
|
||||
Logger.Stub?.PrintStub(LogClass.ServiceNim);
|
||||
|
Reference in New Issue
Block a user