Compare commits

...

3 Commits

Author SHA1 Message Date
gdkchan
e2cfe6fe44 Fix shader GlobalToStorage pass when base address comes from local or shared memory (#5668)
* Fix shader GlobalToStorage pass when base address comes from local or shared memory

* Shader cache version bump
2023-09-11 01:22:18 +00:00
Marco Carvalho
210f475484 Replacing 'Assembly.GetExecutingAssembly()' with 'Type.Assembly' (#5545) 2023-09-07 14:10:58 +02:00
gdkchan
ddb6493896 Delete ResourceAccess (#5626)
* Delete ResourceAccess

* Set write flag for vertex/geometry as compute output buffers
2023-09-05 22:59:21 +02:00
13 changed files with 51 additions and 83 deletions

View File

@@ -15,14 +15,6 @@ namespace Ryujinx.Graphics.GAL
BufferImage, BufferImage,
} }
public enum ResourceAccess : byte
{
None = 0,
Read = 1,
Write = 2,
ReadWrite = Read | Write,
}
[Flags] [Flags]
public enum ResourceStages : byte public enum ResourceStages : byte
{ {
@@ -81,19 +73,17 @@ namespace Ryujinx.Graphics.GAL
public int Binding { get; } public int Binding { get; }
public ResourceType Type { get; } public ResourceType Type { get; }
public ResourceStages Stages { get; } public ResourceStages Stages { get; }
public ResourceAccess Access { get; }
public ResourceUsage(int binding, ResourceType type, ResourceStages stages, ResourceAccess access) public ResourceUsage(int binding, ResourceType type, ResourceStages stages)
{ {
Binding = binding; Binding = binding;
Type = type; Type = type;
Stages = stages; Stages = stages;
Access = access;
} }
public override int GetHashCode() public override int GetHashCode()
{ {
return HashCode.Combine(Binding, Type, Stages, Access); return HashCode.Combine(Binding, Type, Stages);
} }
public override bool Equals(object obj) public override bool Equals(object obj)
@@ -103,7 +93,7 @@ namespace Ryujinx.Graphics.GAL
public bool Equals(ResourceUsage other) public bool Equals(ResourceUsage other)
{ {
return Binding == other.Binding && Type == other.Type && Stages == other.Stages && Access == other.Access; return Binding == other.Binding && Type == other.Type && Stages == other.Stages;
} }
public static bool operator ==(ResourceUsage left, ResourceUsage right) public static bool operator ==(ResourceUsage left, ResourceUsage right)

View File

@@ -490,10 +490,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
/// </summary> /// </summary>
/// <param name="offset">Offset of the range</param> /// <param name="offset">Offset of the range</param>
/// <param name="size">Size of the range in bytes</param> /// <param name="size">Size of the range in bytes</param>
/// <param name="write">Indicates if the buffer contents will be modified</param>
/// <returns>Range</returns> /// <returns>Range</returns>
public BufferRange GetVertexDataBufferRange(int offset, int size) public BufferRange GetVertexDataBufferRange(int offset, int size, bool write)
{ {
return new BufferRange(_vertexDataBuffer.Handle, offset, size); return new BufferRange(_vertexDataBuffer.Handle, offset, size, write);
} }
/// <summary> /// <summary>
@@ -501,10 +502,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
/// </summary> /// </summary>
/// <param name="offset">Offset of the range</param> /// <param name="offset">Offset of the range</param>
/// <param name="size">Size of the range in bytes</param> /// <param name="size">Size of the range in bytes</param>
/// <param name="write">Indicates if the buffer contents will be modified</param>
/// <returns>Range</returns> /// <returns>Range</returns>
public BufferRange GetGeometryVertexDataBufferRange(int offset, int size) public BufferRange GetGeometryVertexDataBufferRange(int offset, int size, bool write)
{ {
return new BufferRange(_geometryVertexDataBuffer.Handle, offset, size); return new BufferRange(_geometryVertexDataBuffer.Handle, offset, size, write);
} }
/// <summary> /// <summary>
@@ -512,10 +514,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
/// </summary> /// </summary>
/// <param name="offset">Offset of the range</param> /// <param name="offset">Offset of the range</param>
/// <param name="size">Size of the range in bytes</param> /// <param name="size">Size of the range in bytes</param>
/// <param name="write">Indicates if the buffer contents will be modified</param>
/// <returns>Range</returns> /// <returns>Range</returns>
public BufferRange GetGeometryIndexDataBufferRange(int offset, int size) public BufferRange GetGeometryIndexDataBufferRange(int offset, int size, bool write)
{ {
return new BufferRange(_geometryIndexDataBuffer.Handle, offset, size); return new BufferRange(_geometryIndexDataBuffer.Handle, offset, size, write);
} }
/// <summary> /// <summary>

View File

@@ -202,7 +202,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
_context.Renderer.Pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(vertexInfoBinding, vertexInfoRange) }); _context.Renderer.Pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(vertexInfoBinding, vertexInfoRange) });
int vertexDataBinding = _vertexAsCompute.Reservations.VertexOutputStorageBufferBinding; int vertexDataBinding = _vertexAsCompute.Reservations.VertexOutputStorageBufferBinding;
BufferRange vertexDataRange = _vacContext.GetVertexDataBufferRange(_vertexDataOffset, _vertexDataSize); BufferRange vertexDataRange = _vacContext.GetVertexDataBufferRange(_vertexDataOffset, _vertexDataSize, write: true);
_context.Renderer.Pipeline.SetStorageBuffers(stackalloc[] { new BufferAssignment(vertexDataBinding, vertexDataRange) }); _context.Renderer.Pipeline.SetStorageBuffers(stackalloc[] { new BufferAssignment(vertexDataBinding, vertexDataRange) });
_vacContext.VertexInfoBufferUpdater.Commit(); _vacContext.VertexInfoBufferUpdater.Commit();
@@ -245,9 +245,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
int geometryVbBinding = _geometryAsCompute.Reservations.GeometryVertexOutputStorageBufferBinding; int geometryVbBinding = _geometryAsCompute.Reservations.GeometryVertexOutputStorageBufferBinding;
int geometryIbBinding = _geometryAsCompute.Reservations.GeometryIndexOutputStorageBufferBinding; int geometryIbBinding = _geometryAsCompute.Reservations.GeometryIndexOutputStorageBufferBinding;
BufferRange vertexDataRange = _vacContext.GetVertexDataBufferRange(_vertexDataOffset, _vertexDataSize); BufferRange vertexDataRange = _vacContext.GetVertexDataBufferRange(_vertexDataOffset, _vertexDataSize, write: false);
BufferRange vertexBuffer = _vacContext.GetGeometryVertexDataBufferRange(_geometryVertexDataOffset, _geometryVertexDataSize); BufferRange vertexBuffer = _vacContext.GetGeometryVertexDataBufferRange(_geometryVertexDataOffset, _geometryVertexDataSize, write: true);
BufferRange indexBuffer = _vacContext.GetGeometryIndexDataBufferRange(_geometryIndexDataOffset, _geometryIndexDataSize); BufferRange indexBuffer = _vacContext.GetGeometryIndexDataBufferRange(_geometryIndexDataOffset, _geometryIndexDataSize, write: true);
_context.Renderer.Pipeline.SetStorageBuffers(stackalloc[] _context.Renderer.Pipeline.SetStorageBuffers(stackalloc[]
{ {
@@ -293,8 +293,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
if (_geometryAsCompute != null) if (_geometryAsCompute != null)
{ {
BufferRange vertexBuffer = _vacContext.GetGeometryVertexDataBufferRange(_geometryVertexDataOffset, _geometryVertexDataSize); BufferRange vertexBuffer = _vacContext.GetGeometryVertexDataBufferRange(_geometryVertexDataOffset, _geometryVertexDataSize, write: false);
BufferRange indexBuffer = _vacContext.GetGeometryIndexDataBufferRange(_geometryIndexDataOffset, _geometryIndexDataSize); BufferRange indexBuffer = _vacContext.GetGeometryIndexDataBufferRange(_geometryIndexDataOffset, _geometryIndexDataSize, write: false);
_context.Renderer.Pipeline.SetProgram(_vertexPassthroughProgram); _context.Renderer.Pipeline.SetProgram(_vertexPassthroughProgram);
_context.Renderer.Pipeline.SetIndexBuffer(indexBuffer, IndexType.UInt); _context.Renderer.Pipeline.SetIndexBuffer(indexBuffer, IndexType.UInt);
@@ -310,7 +310,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
} }
else else
{ {
BufferRange vertexDataRange = _vacContext.GetVertexDataBufferRange(_vertexDataOffset, _vertexDataSize); BufferRange vertexDataRange = _vacContext.GetVertexDataBufferRange(_vertexDataOffset, _vertexDataSize, write: false);
_context.Renderer.Pipeline.SetProgram(_vertexPassthroughProgram); _context.Renderer.Pipeline.SetProgram(_vertexPassthroughProgram);
_context.Renderer.Pipeline.SetStorageBuffers(stackalloc[] { new BufferAssignment(vertexDataBinding, vertexDataRange) }); _context.Renderer.Pipeline.SetStorageBuffers(stackalloc[] { new BufferAssignment(vertexDataBinding, vertexDataRange) });

View File

@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
private const ushort FileFormatVersionMajor = 1; private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 2; private const ushort FileFormatVersionMinor = 2;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
private const uint CodeGenVersion = 5551; private const uint CodeGenVersion = 5668;
private const string SharedTocFileName = "shared.toc"; private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data"; private const string SharedDataFileName = "shared.data";

View File

@@ -61,7 +61,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
} }
AddDescriptor(SupportBufferStages, ResourceType.UniformBuffer, UniformSetIndex, 0, 1); AddDescriptor(SupportBufferStages, ResourceType.UniformBuffer, UniformSetIndex, 0, 1);
AddUsage(SupportBufferStages, ResourceType.UniformBuffer, ResourceAccess.Read, UniformSetIndex, 0, 1); AddUsage(SupportBufferStages, ResourceType.UniformBuffer, UniformSetIndex, 0, 1);
ResourceReservationCounts rrc = new(!context.Capabilities.SupportsTransformFeedback && tfEnabled, vertexAsCompute); ResourceReservationCounts rrc = new(!context.Capabilities.SupportsTransformFeedback && tfEnabled, vertexAsCompute);
@@ -73,16 +73,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
// TODO: Handle that better? Maybe we should only set the binding that are really needed on each shader. // TODO: Handle that better? Maybe we should only set the binding that are really needed on each shader.
ResourceStages stages = vertexAsCompute ? ResourceStages.Compute | ResourceStages.Vertex : VtgStages; ResourceStages stages = vertexAsCompute ? ResourceStages.Compute | ResourceStages.Vertex : VtgStages;
PopulateDescriptorAndUsages(stages, ResourceType.UniformBuffer, ResourceAccess.Read, UniformSetIndex, 1, rrc.ReservedConstantBuffers - 1); PopulateDescriptorAndUsages(stages, ResourceType.UniformBuffer, UniformSetIndex, 1, rrc.ReservedConstantBuffers - 1);
PopulateDescriptorAndUsages(stages, ResourceType.StorageBuffer, ResourceAccess.ReadWrite, StorageSetIndex, 0, rrc.ReservedStorageBuffers); PopulateDescriptorAndUsages(stages, ResourceType.StorageBuffer, StorageSetIndex, 0, rrc.ReservedStorageBuffers);
PopulateDescriptorAndUsages(stages, ResourceType.BufferTexture, ResourceAccess.Read, TextureSetIndex, 0, rrc.ReservedTextures); PopulateDescriptorAndUsages(stages, ResourceType.BufferTexture, TextureSetIndex, 0, rrc.ReservedTextures);
PopulateDescriptorAndUsages(stages, ResourceType.BufferImage, ResourceAccess.ReadWrite, ImageSetIndex, 0, rrc.ReservedImages); PopulateDescriptorAndUsages(stages, ResourceType.BufferImage, ImageSetIndex, 0, rrc.ReservedImages);
} }
private void PopulateDescriptorAndUsages(ResourceStages stages, ResourceType type, ResourceAccess access, int setIndex, int start, int count) private void PopulateDescriptorAndUsages(ResourceStages stages, ResourceType type, int setIndex, int start, int count)
{ {
AddDescriptor(stages, type, setIndex, start, count); AddDescriptor(stages, type, setIndex, start, count);
AddUsage(stages, type, access, setIndex, start, count); AddUsage(stages, type, setIndex, start, count);
} }
/// <summary> /// <summary>
@@ -174,15 +174,14 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// </summary> /// </summary>
/// <param name="stages">Shader stages where the resource is used</param> /// <param name="stages">Shader stages where the resource is used</param>
/// <param name="type">Type of the resource</param> /// <param name="type">Type of the resource</param>
/// <param name="access">How the resource is accessed by the shader stages where it is used</param>
/// <param name="setIndex">Descriptor set number where the resource will be bound</param> /// <param name="setIndex">Descriptor set number where the resource will be bound</param>
/// <param name="binding">Binding number where the resource will be bound</param> /// <param name="binding">Binding number where the resource will be bound</param>
/// <param name="count">Number of resources bound at the binding location</param> /// <param name="count">Number of resources bound at the binding location</param>
private void AddUsage(ResourceStages stages, ResourceType type, ResourceAccess access, int setIndex, int binding, int count) private void AddUsage(ResourceStages stages, ResourceType type, int setIndex, int binding, int count)
{ {
for (int index = 0; index < count; index++) for (int index = 0; index < count; index++)
{ {
_resourceUsages[setIndex].Add(new ResourceUsage(binding + index, type, stages, access)); _resourceUsages[setIndex].Add(new ResourceUsage(binding + index, type, stages));
} }
} }
@@ -200,8 +199,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
_resourceUsages[setIndex].Add(new ResourceUsage( _resourceUsages[setIndex].Add(new ResourceUsage(
buffer.Binding, buffer.Binding,
isStorage ? ResourceType.StorageBuffer : ResourceType.UniformBuffer, isStorage ? ResourceType.StorageBuffer : ResourceType.UniformBuffer,
stages, stages));
buffer.Flags.HasFlag(BufferUsageFlags.Write) ? ResourceAccess.ReadWrite : ResourceAccess.Read));
} }
} }
@@ -225,8 +223,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
_resourceUsages[setIndex].Add(new ResourceUsage( _resourceUsages[setIndex].Add(new ResourceUsage(
texture.Binding, texture.Binding,
type, type,
stages, stages));
texture.Flags.HasFlag(TextureUsageFlags.ImageStore) ? ResourceAccess.ReadWrite : ResourceAccess.Read));
} }
} }

View File

@@ -1126,7 +1126,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
// so we want to get the byte offset back, since each one of those word // so we want to get the byte offset back, since each one of those word
// offsets are a new "local variable" which will not match. // offsets are a new "local variable" which will not match.
if (operation.GetSource(0).AsgOp is Operation shiftRightOp && if (operation.GetSource(1).AsgOp is Operation shiftRightOp &&
shiftRightOp.Inst == Instruction.ShiftRightU32 && shiftRightOp.Inst == Instruction.ShiftRightU32 &&
shiftRightOp.GetSource(1).Type == OperandType.Constant && shiftRightOp.GetSource(1).Type == OperandType.Constant &&
shiftRightOp.GetSource(1).Value == 2) shiftRightOp.GetSource(1).Value == 2)
@@ -1158,9 +1158,11 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
private static bool TryGetLocalMemoryOffset(Operation operation, out int constOffset) private static bool TryGetLocalMemoryOffset(Operation operation, out int constOffset)
{ {
if (operation.GetSource(0).Type == OperandType.Constant) Operand offset = operation.GetSource(1);
if (offset.Type == OperandType.Constant)
{ {
constOffset = operation.GetSource(0).Value; constOffset = offset.Value;
return true; return true;
} }

View File

@@ -8,15 +8,13 @@ namespace Ryujinx.Graphics.Vulkan
public readonly int Count; public readonly int Count;
public readonly ResourceType Type; public readonly ResourceType Type;
public readonly ResourceStages Stages; public readonly ResourceStages Stages;
public readonly ResourceAccess Access;
public ResourceBindingSegment(int binding, int count, ResourceType type, ResourceStages stages, ResourceAccess access) public ResourceBindingSegment(int binding, int count, ResourceType type, ResourceStages stages)
{ {
Binding = binding; Binding = binding;
Count = count; Count = count;
Type = type; Type = type;
Stages = stages; Stages = stages;
Access = access;
} }
} }
} }

View File

@@ -34,22 +34,12 @@ namespace Ryujinx.Graphics.Vulkan
_ => throw new ArgumentException($"Invalid resource type \"{type}\"."), _ => throw new ArgumentException($"Invalid resource type \"{type}\"."),
}; };
ResourceAccess access = IsReadOnlyType(type) ? ResourceAccess.Read : ResourceAccess.ReadWrite;
_resourceDescriptors[setIndex].Add(new ResourceDescriptor(binding, 1, type, stages)); _resourceDescriptors[setIndex].Add(new ResourceDescriptor(binding, 1, type, stages));
_resourceUsages[setIndex].Add(new ResourceUsage(binding, type, stages, access)); _resourceUsages[setIndex].Add(new ResourceUsage(binding, type, stages));
return this; return this;
} }
private static bool IsReadOnlyType(ResourceType type)
{
return type == ResourceType.UniformBuffer ||
type == ResourceType.Sampler ||
type == ResourceType.TextureAndSampler ||
type == ResourceType.BufferTexture;
}
public ResourceLayout Build() public ResourceLayout Build()
{ {
var descriptors = new ResourceDescriptorCollection[TotalSets]; var descriptors = new ResourceDescriptorCollection[TotalSets];

View File

@@ -162,8 +162,7 @@ namespace Ryujinx.Graphics.Vulkan
currentDescriptor.Binding, currentDescriptor.Binding,
currentCount, currentCount,
currentDescriptor.Type, currentDescriptor.Type,
currentDescriptor.Stages, currentDescriptor.Stages));
ResourceAccess.ReadWrite));
} }
currentDescriptor = descriptor; currentDescriptor = descriptor;
@@ -181,8 +180,7 @@ namespace Ryujinx.Graphics.Vulkan
currentDescriptor.Binding, currentDescriptor.Binding,
currentCount, currentCount,
currentDescriptor.Type, currentDescriptor.Type,
currentDescriptor.Stages, currentDescriptor.Stages));
ResourceAccess.ReadWrite));
} }
segments[setIndex] = currentSegments.ToArray(); segments[setIndex] = currentSegments.ToArray();
@@ -206,16 +204,9 @@ namespace Ryujinx.Graphics.Vulkan
{ {
ResourceUsage usage = setUsages[setIndex].Usages[index]; ResourceUsage usage = setUsages[setIndex].Usages[index];
// If the resource is not accessed, we don't need to update it.
if (usage.Access == ResourceAccess.None)
{
continue;
}
if (currentUsage.Binding + currentCount != usage.Binding || if (currentUsage.Binding + currentCount != usage.Binding ||
currentUsage.Type != usage.Type || currentUsage.Type != usage.Type ||
currentUsage.Stages != usage.Stages || currentUsage.Stages != usage.Stages)
currentUsage.Access != usage.Access)
{ {
if (currentCount != 0) if (currentCount != 0)
{ {
@@ -223,8 +214,7 @@ namespace Ryujinx.Graphics.Vulkan
currentUsage.Binding, currentUsage.Binding,
currentCount, currentCount,
currentUsage.Type, currentUsage.Type,
currentUsage.Stages, currentUsage.Stages));
currentUsage.Access));
} }
currentUsage = usage; currentUsage = usage;
@@ -242,8 +232,7 @@ namespace Ryujinx.Graphics.Vulkan
currentUsage.Binding, currentUsage.Binding,
currentCount, currentCount,
currentUsage.Type, currentUsage.Type,
currentUsage.Stages, currentUsage.Stages));
currentUsage.Access));
} }
segments[setIndex] = currentSegments.ToArray(); segments[setIndex] = currentSegments.ToArray();

View File

@@ -68,15 +68,15 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
int ryujinxLogoSize = 32; int ryujinxLogoSize = 32;
string ryujinxIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Logo_Ryujinx.png"; string ryujinxIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Logo_Ryujinx.png";
_ryujinxLogo = LoadResource(Assembly.GetExecutingAssembly(), ryujinxIconPath, ryujinxLogoSize, ryujinxLogoSize); _ryujinxLogo = LoadResource(typeof(SoftwareKeyboardRendererBase).Assembly, ryujinxIconPath, ryujinxLogoSize, ryujinxLogoSize);
string padAcceptIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Icon_BtnA.png"; string padAcceptIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Icon_BtnA.png";
string padCancelIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Icon_BtnB.png"; string padCancelIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Icon_BtnB.png";
string keyModeIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Icon_KeyF6.png"; string keyModeIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Icon_KeyF6.png";
_padAcceptIcon = LoadResource(Assembly.GetExecutingAssembly(), padAcceptIconPath, 0, 0); _padAcceptIcon = LoadResource(typeof(SoftwareKeyboardRendererBase).Assembly, padAcceptIconPath, 0, 0);
_padCancelIcon = LoadResource(Assembly.GetExecutingAssembly(), padCancelIconPath, 0, 0); _padCancelIcon = LoadResource(typeof(SoftwareKeyboardRendererBase).Assembly, padCancelIconPath, 0, 0);
_keyModeIcon = LoadResource(Assembly.GetExecutingAssembly(), keyModeIconPath, 0, 0); _keyModeIcon = LoadResource(typeof(SoftwareKeyboardRendererBase).Assembly, keyModeIconPath, 0, 0);
Color panelColor = ToColor(uiTheme.DefaultBackgroundColor, 255); Color panelColor = ToColor(uiTheme.DefaultBackgroundColor, 255);
Color panelTransparentColor = ToColor(uiTheme.DefaultBackgroundColor, 150); Color panelTransparentColor = ToColor(uiTheme.DefaultBackgroundColor, 150);

View File

@@ -23,14 +23,14 @@ namespace Ryujinx.HLE.HOS.Services
public IpcService(ServerBase server = null) public IpcService(ServerBase server = null)
{ {
CmifCommands = Assembly.GetExecutingAssembly().GetTypes() CmifCommands = typeof(IpcService).Assembly.GetTypes()
.Where(type => type == GetType()) .Where(type => type == GetType())
.SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)) .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public))
.SelectMany(methodInfo => methodInfo.GetCustomAttributes(typeof(CommandCmifAttribute)) .SelectMany(methodInfo => methodInfo.GetCustomAttributes(typeof(CommandCmifAttribute))
.Select(command => (((CommandCmifAttribute)command).Id, methodInfo))) .Select(command => (((CommandCmifAttribute)command).Id, methodInfo)))
.ToDictionary(command => command.Id, command => command.methodInfo); .ToDictionary(command => command.Id, command => command.methodInfo);
TipcCommands = Assembly.GetExecutingAssembly().GetTypes() TipcCommands = typeof(IpcService).Assembly.GetTypes()
.Where(type => type == GetType()) .Where(type => type == GetType())
.SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)) .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public))
.SelectMany(methodInfo => methodInfo.GetCustomAttributes(typeof(CommandTipcAttribute)) .SelectMany(methodInfo => methodInfo.GetCustomAttributes(typeof(CommandTipcAttribute))

View File

@@ -28,7 +28,7 @@ namespace Ryujinx.HLE.HOS.Services.Sm
static IUserInterface() static IUserInterface()
{ {
_services = Assembly.GetExecutingAssembly().GetTypes() _services = typeof(IUserInterface).Assembly.GetTypes()
.SelectMany(type => type.GetCustomAttributes(typeof(ServiceAttribute), true) .SelectMany(type => type.GetCustomAttributes(typeof(ServiceAttribute), true)
.Select(service => (((ServiceAttribute)service).Name, type))) .Select(service => (((ServiceAttribute)service).Name, type)))
.ToDictionary(service => service.Name, service => service.type); .ToDictionary(service => service.Name, service => service.type);

View File

@@ -17,7 +17,6 @@ using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using static SDL2.SDL; using static SDL2.SDL;
@@ -122,7 +121,7 @@ namespace Ryujinx.Headless.SDL2
private void SetWindowIcon() private void SetWindowIcon()
{ {
Stream iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Ryujinx.Headless.SDL2.Ryujinx.bmp"); Stream iconStream = typeof(WindowBase).Assembly.GetManifestResourceStream("Ryujinx.Headless.SDL2.Ryujinx.bmp");
byte[] iconBytes = new byte[iconStream!.Length]; byte[] iconBytes = new byte[iconStream!.Length];
if (iconStream.Read(iconBytes, 0, iconBytes.Length) != iconBytes.Length) if (iconStream.Read(iconBytes, 0, iconBytes.Length) != iconBytes.Length)