diff --git a/Ryujinx.Graphics.GAL/Capabilities.cs b/Ryujinx.Graphics.GAL/Capabilities.cs
index f06c3c4b4..b75ceb94f 100644
--- a/Ryujinx.Graphics.GAL/Capabilities.cs
+++ b/Ryujinx.Graphics.GAL/Capabilities.cs
@@ -5,20 +5,17 @@ namespace Ryujinx.Graphics.GAL
public bool SupportsAstcCompression { get; }
public bool SupportsNonConstantTextureOffset { get; }
- public int MaximumViewportDimensions { get; }
public int MaximumComputeSharedMemorySize { get; }
public int StorageBufferOffsetAlignment { get; }
public Capabilities(
bool supportsAstcCompression,
bool supportsNonConstantTextureOffset,
- int maximumViewportDimensions,
int maximumComputeSharedMemorySize,
int storageBufferOffsetAlignment)
{
SupportsAstcCompression = supportsAstcCompression;
SupportsNonConstantTextureOffset = supportsNonConstantTextureOffset;
- MaximumViewportDimensions = maximumViewportDimensions;
MaximumComputeSharedMemorySize = maximumComputeSharedMemorySize;
StorageBufferOffsetAlignment = storageBufferOffsetAlignment;
}
diff --git a/Ryujinx.Graphics.Gpu/Constants.cs b/Ryujinx.Graphics.Gpu/Constants.cs
index ff5b9f94c..65cd8846d 100644
--- a/Ryujinx.Graphics.Gpu/Constants.cs
+++ b/Ryujinx.Graphics.Gpu/Constants.cs
@@ -11,7 +11,7 @@ namespace Ryujinx.Graphics.Gpu
public const int TotalCpUniformBuffers = 8;
///
- /// Maximum number of compute storage buffers (this is a API limitation).
+ /// Maximum number of compute storage buffers (this is an API limitation).
///
public const int TotalCpStorageBuffers = 16;
@@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.Gpu
public const int TotalGpUniformBuffers = 18;
///
- /// Maximum number of graphics storage buffers (this is a API limitation).
+ /// Maximum number of graphics storage buffers (this is an API limitation).
///
public const int TotalGpStorageBuffers = 16;
@@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.Gpu
///
/// Number of shader stages.
///
- public const int TotalShaderStages = 5;
+ public const int ShaderStages = 5;
///
/// Maximum number of vertex buffers.
diff --git a/Ryujinx.Graphics.Gpu/DmaPusher.cs b/Ryujinx.Graphics.Gpu/DmaPusher.cs
index d90bbd731..1c85686a5 100644
--- a/Ryujinx.Graphics.Gpu/DmaPusher.cs
+++ b/Ryujinx.Graphics.Gpu/DmaPusher.cs
@@ -86,7 +86,7 @@ namespace Ryujinx.Graphics.Gpu
///
/// Processes a single command on the FIFO.
///
- ///
+ /// True if the FIFO still has commands to be processed, false otherwise
private bool Step()
{
if (_dmaGet != _dmaPut)
diff --git a/Ryujinx.Graphics.Gpu/Engine/MethodReport.cs b/Ryujinx.Graphics.Gpu/Engine/MethodReport.cs
index 8418f0bb5..4b6b8fd0a 100644
--- a/Ryujinx.Graphics.Gpu/Engine/MethodReport.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/MethodReport.cs
@@ -8,6 +8,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
{
partial class Methods
{
+ private const int NsToTicksFractionNumerator = 384;
+ private const int NsToTicksFractionDenominator = 625;
+
private ulong _runningCounter;
///
@@ -103,8 +106,10 @@ namespace Ryujinx.Graphics.Gpu.Engine
///
/// Converts a nanoseconds timestamp value to Maxwell time ticks.
- /// The frequency is approximately 1.63Hz.
///
+ ///
+ /// The frequency is 614400000 Hz.
+ ///
/// Timestamp in nanoseconds
/// Maxwell ticks
private static ulong ConvertNanosecondsToTicks(ulong nanoseconds)
@@ -112,13 +117,13 @@ namespace Ryujinx.Graphics.Gpu.Engine
// We need to divide first to avoid overflows.
// We fix up the result later by calculating the difference and adding
// that to the result.
- ulong divided = nanoseconds / 625;
+ ulong divided = nanoseconds / NsToTicksFractionDenominator;
- ulong rounded = divided * 625;
+ ulong rounded = divided * NsToTicksFractionDenominator;
- ulong errorBias = ((nanoseconds - rounded) * 384) / 625;
+ ulong errorBias = (nanoseconds - rounded) * NsToTicksFractionNumerator / NsToTicksFractionDenominator;
- return divided * 384 + errorBias;
+ return divided * NsToTicksFractionNumerator + errorBias;
}
}
}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Gpu/Engine/Methods.cs b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
index 6dce61f2b..d832c62e7 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Methods.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
@@ -48,7 +48,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
ShaderCache = new ShaderCache(_context);
- _currentProgramInfo = new ShaderProgramInfo[Constants.TotalShaderStages];
+ _currentProgramInfo = new ShaderProgramInfo[Constants.ShaderStages];
BufferManager = new BufferManager(context);
TextureManager = new TextureManager(context);
@@ -201,7 +201,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
///
/// Ensures that the bindings are visible to the host GPU.
- /// This actually performs the binding using the host graphics API.
+ /// Note: this actually performs the binding using the host graphics API.
///
private void CommitBindings()
{
@@ -622,7 +622,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
///
/// Updates host render target color masks, based on guest GPU state.
- /// This defines with color channels are written to each color buffer.
+ /// This defines which color channels are written to each color buffer.
///
/// Current GPU state
private void UpdateRtColorMask(GpuState state)
@@ -739,7 +739,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
_vsUsesInstanceId = gs.Shaders[0].Program.Info.UsesInstanceId;
- for (int stage = 0; stage < Constants.TotalShaderStages; stage++)
+ for (int stage = 0; stage < Constants.ShaderStages; stage++)
{
ShaderProgramInfo info = gs.Shaders[stage].Program?.Info;
@@ -845,7 +845,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
return Target.CubemapArray;
}
- // TODO: Warning.
+ Logger.PrintWarning(LogClass.Gpu, $"Invalid sampler type \"{type}\".");
return Target.Texture2D;
}
@@ -855,8 +855,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
/// This waits until previous texture writes from the GPU to finish, before
/// performing new operations with said textures.
///
- /// Current GPU state
- /// Method call argument
+ /// Current GPU state (unused)
+ /// Method call argument (unused)
private void TextureBarrier(GpuState state, int argument)
{
_context.Renderer.Pipeline.TextureBarrier();
@@ -865,8 +865,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
///
/// Invalidates all modified textures on the cache.
///
- /// Current GPU state
- /// Method call argument
+ /// Current GPU state (unused)
+ /// Method call argument (unused)
private void InvalidateTextures(GpuState state, int argument)
{
TextureManager.Flush();
@@ -880,8 +880,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
/// and current access has the same access patterns.
/// This may be faster than the regular barrier on tile-based rasterizers.
///
- ///
- ///
+ /// Current GPU state (unused)
+ /// Method call argument (unused)
private void TextureBarrierTiled(GpuState state, int argument)
{
_context.Renderer.Pipeline.TextureBarrierTiled();
diff --git a/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs b/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs
index fc30d03c7..d66eab93f 100644
--- a/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs
+++ b/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs
@@ -24,9 +24,11 @@ namespace Ryujinx.Graphics.Gpu.Image
///
/// Adds a new texture to the cache, even if the texture added is already on the cache.
+ ///
+ ///
/// Using this method is only recommended if you know that the texture is not yet on the cache,
/// otherwise it would store the same texture more than once.
- ///
+ ///
/// The texture to be added to the cache
public void Add(Texture texture)
{
@@ -48,9 +50,12 @@ namespace Ryujinx.Graphics.Gpu.Image
///
/// Adds a new texture to the cache, or just moves it to the top of the list if the
- /// texture is already on the cache. Moving the texture to the top of the list prevents
- /// it from being deleted, as the textures on the bottom of the list are deleted when new ones are added.
+ /// texture is already on the cache.
///
+ ///
+ /// Moving the texture to the top of the list prevents it from being deleted,
+ /// as the textures on the bottom of the list are deleted when new ones are added.
+ ///
/// The texture to be added, or moved to the top
public void Lift(Texture texture)
{
diff --git a/Ryujinx.Graphics.Gpu/Image/FormatInfo.cs b/Ryujinx.Graphics.Gpu/Image/FormatInfo.cs
index 4f73bfa86..12f3aecbb 100644
--- a/Ryujinx.Graphics.Gpu/Image/FormatInfo.cs
+++ b/Ryujinx.Graphics.Gpu/Image/FormatInfo.cs
@@ -18,13 +18,19 @@ namespace Ryujinx.Graphics.Gpu.Image
public Format Format { get; }
///
- /// The block width for compressed formats. Must be 1 for non-compressed formats.
+ /// The block width for compressed formats.
///
+ ///
+ /// Must be 1 for non-compressed formats.
+ ///
public int BlockWidth { get; }
///
- /// The block height for compressed formats. Must be 1 for non-compressed formats.
+ /// The block height for compressed formats.
///
+ ///
+ /// Must be 1 for non-compressed formats.
+ ///
public int BlockHeight { get; }
///
diff --git a/Ryujinx.Graphics.Gpu/Image/Pool.cs b/Ryujinx.Graphics.Gpu/Image/Pool.cs
index bb55d40e1..e4cefe9cb 100644
--- a/Ryujinx.Graphics.Gpu/Image/Pool.cs
+++ b/Ryujinx.Graphics.Gpu/Image/Pool.cs
@@ -17,8 +17,10 @@ namespace Ryujinx.Graphics.Gpu.Image
///
/// The maximum ID value of resources on the pool (inclusive).
- /// The maximum amount of resources on the pool is equal to this value plus one.
///
+ ///
+ /// The maximum amount of resources on the pool is equal to this value plus one.
+ ///
public int MaximumId { get; }
///
diff --git a/Ryujinx.Graphics.Gpu/Image/ReductionFilter.cs b/Ryujinx.Graphics.Gpu/Image/ReductionFilter.cs
index 94b3f5425..1f7d9b070 100644
--- a/Ryujinx.Graphics.Gpu/Image/ReductionFilter.cs
+++ b/Ryujinx.Graphics.Gpu/Image/ReductionFilter.cs
@@ -2,8 +2,10 @@ namespace Ryujinx.Graphics.Gpu.Image
{
///
/// Represents a filter used with texture minification linear filtering.
- /// This feature is only supported on NVIDIA GPUs.
///
+ ///
+ /// This feature is only supported on NVIDIA GPUs.
+ ///
enum ReductionFilter
{
Average,
diff --git a/Ryujinx.Graphics.Gpu/Image/Texture.cs b/Ryujinx.Graphics.Gpu/Image/Texture.cs
index 4bbefd0bc..be3d622f9 100644
--- a/Ryujinx.Graphics.Gpu/Image/Texture.cs
+++ b/Ryujinx.Graphics.Gpu/Image/Texture.cs
@@ -190,9 +190,11 @@ namespace Ryujinx.Graphics.Gpu.Image
///
/// Changes the texture size.
+ ///
+ ///
/// This operation may also change the size of all mipmap levels, including from the parent
/// and other possible child textures, to ensure that all sizes are consistent.
- ///
+ ///
/// The new texture width
/// The new texture height
/// The new texture depth (for 3D textures) or layers (for layered textures)
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureBindingInfo.cs b/Ryujinx.Graphics.Gpu/Image/TextureBindingInfo.cs
index 94225406e..91a5fcf60 100644
--- a/Ryujinx.Graphics.Gpu/Image/TextureBindingInfo.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TextureBindingInfo.cs
@@ -21,8 +21,10 @@ namespace Ryujinx.Graphics.Gpu.Image
///
/// Indicates if the texture is a bindless texture.
- /// For those textures, Handle is ignored.
///
+ ///
+ /// For those textures, Handle is ignored.
+ ///
public bool IsBindless { get; }
///
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs
index 4d50c46e3..984d45a95 100644
--- a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs
@@ -52,7 +52,7 @@ namespace Ryujinx.Graphics.Gpu.Image
_texturePoolCache = texturePoolCache;
_isCompute = isCompute;
- int stages = isCompute ? 1 : Constants.TotalShaderStages;
+ int stages = isCompute ? 1 : Constants.ShaderStages;
_textureBindings = new TextureBindingInfo[stages][];
_imageBindings = new TextureBindingInfo[stages][];
@@ -135,7 +135,7 @@ namespace Ryujinx.Graphics.Gpu.Image
///
/// Ensures that the bindings are visible to the host GPU.
- /// This actually performs the binding using the host graphics API.
+ /// Note: this actually performs the binding using the host graphics API.
///
public void CommitBindings()
{
@@ -164,7 +164,7 @@ namespace Ryujinx.Graphics.Gpu.Image
///
/// Ensures that the texture bindings are visible to the host GPU.
- /// This actually performs the binding using the host graphics API.
+ /// Note: this actually performs the binding using the host graphics API.
///
/// The current texture pool
/// The shader stage using the textures to be bound
@@ -242,7 +242,7 @@ namespace Ryujinx.Graphics.Gpu.Image
///
/// Ensures that the image bindings are visible to the host GPU.
- /// This actually performs the binding using the host graphics API.
+ /// Note: this actually performs the binding using the host graphics API.
///
/// The current texture pool
/// The shader stage using the textures to be bound
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs
index e0a8908aa..387e908d6 100644
--- a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs
@@ -753,9 +753,11 @@ namespace Ryujinx.Graphics.Gpu.Image
///
/// Removes a texture from the cache.
+ ///
+ ///
/// This only removes the texture from the internal list, not from the auto-deletion cache.
/// It may still have live references after the removal.
- ///
+ ///
/// The texture to be removed
public void RemoveTextureFromCache(Texture texture)
{
diff --git a/Ryujinx.Graphics.Gpu/MacroInterpreter.cs b/Ryujinx.Graphics.Gpu/MacroInterpreter.cs
index cfc3815b0..63a5986ac 100644
--- a/Ryujinx.Graphics.Gpu/MacroInterpreter.cs
+++ b/Ryujinx.Graphics.Gpu/MacroInterpreter.cs
@@ -388,7 +388,7 @@ namespace Ryujinx.Graphics.Gpu
///
/// Extracts a 32-bits signed integer constant from the current operation code.
///
- ///
+ /// The 32-bits immediate value encoded at the current operation code
private int GetImm()
{
// Note: The immediate is signed, the sign-extension is intended here.
diff --git a/Ryujinx.Graphics.Gpu/Memory/Buffer.cs b/Ryujinx.Graphics.Gpu/Memory/Buffer.cs
index 8af61d3d8..4210ecb98 100644
--- a/Ryujinx.Graphics.Gpu/Memory/Buffer.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/Buffer.cs
@@ -53,9 +53,11 @@ namespace Ryujinx.Graphics.Gpu.Memory
///
/// Gets a sub-range from the buffer.
- /// This can be used to bind and use sub-ranges of the buffer on the host API.
///
- /// Start address of the sub-range, must be greater or equal to the buffer address
+ ///
+ /// This can be used to bind and use sub-ranges of the buffer on the host API.
+ ///
+ /// Start address of the sub-range, must be greater than or equal to the buffer address
/// Size in bytes of the sub-range, must be less than or equal to the buffer size
/// The buffer sub-range
public BufferRange GetRange(ulong address, ulong size)
@@ -78,9 +80,11 @@ namespace Ryujinx.Graphics.Gpu.Memory
///
/// Performs guest to host memory synchronization of the buffer data.
+ ///
+ ///
/// This causes the buffer data to be overwritten if a write was detected from the CPU,
/// since the last call to this method.
- ///
+ ///
/// Start address of the range to synchronize
/// Size in bytes of the range to synchronize
public void SynchronizeMemory(ulong address, ulong size)
diff --git a/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs b/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs
index 44542349d..de56bacaf 100644
--- a/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs
@@ -76,10 +76,10 @@ namespace Ryujinx.Graphics.Gpu.Memory
_cpStorageBuffers = new BuffersPerStage(Constants.TotalCpStorageBuffers);
_cpUniformBuffers = new BuffersPerStage(Constants.TotalCpUniformBuffers);
- _gpStorageBuffers = new BuffersPerStage[Constants.TotalShaderStages];
- _gpUniformBuffers = new BuffersPerStage[Constants.TotalShaderStages];
+ _gpStorageBuffers = new BuffersPerStage[Constants.ShaderStages];
+ _gpUniformBuffers = new BuffersPerStage[Constants.ShaderStages];
- for (int index = 0; index < Constants.TotalShaderStages; index++)
+ for (int index = 0; index < Constants.ShaderStages; index++)
{
_gpStorageBuffers[index] = new BuffersPerStage(Constants.TotalGpStorageBuffers);
_gpUniformBuffers[index] = new BuffersPerStage(Constants.TotalGpUniformBuffers);
@@ -387,7 +387,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
///
/// Ensures that the compute engine bindings are visible to the host GPU.
- /// This actually performs the binding using the host graphics API.
+ /// Note: this actually performs the binding using the host graphics API.
///
public void CommitComputeBindings()
{
@@ -439,7 +439,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
///
/// Ensures that the graphics engine bindings are visible to the host GPU.
- /// This actually performs the binding using the host graphics API.
+ /// Note: this actually performs the binding using the host graphics API.
///
public void CommitBindings()
{
@@ -543,11 +543,11 @@ namespace Ryujinx.Graphics.Gpu.Memory
}
///
- /// This binds buffer into the host API, or updates data for already bound buffers.
+ /// This binds buffers into the host API, or updates data for already bound buffers.
///
/// Bindings to bind or update
/// True to bind, false to update
- /// True to bind as storage buffer, false to bind as uniform buffers
+ /// True to bind as storage buffer, false to bind as uniform buffer
private void BindOrUpdateBuffers(BuffersPerStage[] bindings, bool bind, bool isStorage = false)
{
for (ShaderStage stage = ShaderStage.Vertex; stage <= ShaderStage.Fragment; stage++)
@@ -608,8 +608,10 @@ namespace Ryujinx.Graphics.Gpu.Memory
///
/// Copy a buffer data from a given address to another.
- /// This does a GPU side copy.
///
+ ///
+ /// This does a GPU side copy.
+ ///
/// GPU virtual address of the copy source
/// GPU virtual address of the copy destination
/// Size in bytes of the copy
diff --git a/Ryujinx.Graphics.Gpu/Memory/MemoryAccessor.cs b/Ryujinx.Graphics.Gpu/Memory/MemoryAccessor.cs
index 3cbbd2536..187793331 100644
--- a/Ryujinx.Graphics.Gpu/Memory/MemoryAccessor.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/MemoryAccessor.cs
@@ -50,7 +50,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
/// Reads a structure from GPU mapped memory.
///
/// Type of the structure
- /// GPU virtual address where the strcture is located
+ /// GPU virtual address where the structure is located
/// The structure at the specified memory location
public T Read(ulong gpuVa) where T : struct
{
diff --git a/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs b/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
index 33be04d39..d0171b420 100644
--- a/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
@@ -39,8 +39,10 @@ namespace Ryujinx.Graphics.Gpu.Memory
///
/// Maps a given range of pages to the specified CPU virtual address.
- /// All addresses and sizes must be page aligned.
///
+ ///
+ /// All addresses and sizes must be page aligned.
+ ///
/// CPU virtual address to map into
/// GPU virtual address to be mapped
/// Size in bytes of the mapping
@@ -59,7 +61,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
}
///
- /// Maps a given range of pages to a allocated GPU virtual address.
+ /// Maps a given range of pages to an allocated GPU virtual address.
/// The memory is automatically allocated by the memory manager.
///
/// CPU virtual address to map into
@@ -84,7 +86,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
}
///
- /// Maps a given range of pages to a allocated GPU virtual address.
+ /// Maps a given range of pages to an allocated GPU virtual address.
/// The memory is automatically allocated by the memory manager.
/// This also ensures that the mapping is always done in the first 4GB of GPU address space.
///
diff --git a/Ryujinx.Graphics.Gpu/Memory/RangeList.cs b/Ryujinx.Graphics.Gpu/Memory/RangeList.cs
index 638108fe7..d65814b3f 100644
--- a/Ryujinx.Graphics.Gpu/Memory/RangeList.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/RangeList.cs
@@ -77,9 +77,11 @@ namespace Ryujinx.Graphics.Gpu.Memory
///
/// Gets the first item on the list overlapping in memory with the specified item.
+ ///
+ ///
/// Despite the name, this has no ordering guarantees of the returned item.
/// It only ensures that the item returned overlaps the specified item.
- ///
+ ///
/// Item to check for overlaps
/// The overlapping item, or the default value for the type if none found
public T FindFirstOverlap(T item)
@@ -89,9 +91,11 @@ namespace Ryujinx.Graphics.Gpu.Memory
///
/// Gets the first item on the list overlapping the specified memory range.
+ ///
+ ///
/// Despite the name, this has no ordering guarantees of the returned item.
/// It only ensures that the item returned overlaps the specified memory range.
- ///
+ ///
/// Start address of the range
/// Size in bytes or the rangee
/// The overlapping item, or the default value for the type if none found
@@ -157,10 +161,12 @@ namespace Ryujinx.Graphics.Gpu.Memory
///
/// Gets all items overlapping with the specified item in memory.
+ ///
+ ///
/// This method only returns correct results if none of the items on the list overlaps with
/// each other. If that is not the case, this method should not be used.
/// This method is faster than the regular method to find all overlaps.
- ///
+ ///
/// Item to check for overlaps
/// Output array where matches will be written. It is automatically resized to fit the results
/// The number of overlapping items found
@@ -171,10 +177,12 @@ namespace Ryujinx.Graphics.Gpu.Memory
///
/// Gets all items on the list overlapping the specified memory range.
+ ///
+ ///
/// This method only returns correct results if none of the items on the list overlaps with
/// each other. If that is not the case, this method should not be used.
/// This method is faster than the regular method to find all overlaps.
- ///
+ ///
/// Start address of the range
/// Size in bytes or the rangee
/// Output array where matches will be written. It is automatically resized to fit the results
diff --git a/Ryujinx.Graphics.Gpu/Shader/GraphicsShader.cs b/Ryujinx.Graphics.Gpu/Shader/GraphicsShader.cs
index a14932364..e348f304f 100644
--- a/Ryujinx.Graphics.Gpu/Shader/GraphicsShader.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/GraphicsShader.cs
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
///
public GraphicsShader()
{
- Shaders = new CachedShader[5];
+ Shaders = new CachedShader[Constants.ShaderStages];
}
}
}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
index 02837cbb1..9f0c1c133 100644
--- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu.Image;
using Ryujinx.Graphics.Gpu.State;
@@ -45,8 +46,10 @@ namespace Ryujinx.Graphics.Gpu.Shader
///
/// Gets a compute shader from the cache.
- /// This automatically translates, compiles and adds the code to the cache if not present.
///
+ ///
+ /// This automatically translates, compiles and adds the code to the cache if not present.
+ ///
/// GPU virtual address of the binary shader code
/// Shared memory size of the compute shader
/// Local group size X of the computer shader
@@ -93,8 +96,10 @@ namespace Ryujinx.Graphics.Gpu.Shader
///
/// Gets a graphics shader program from the shader cache.
/// This includes all the specified shader stages.
- /// This automatically translates, compiles and adds the code to the cache if not present.
///
+ ///
+ /// This automatically translates, compiles and adds the code to the cache if not present.
+ ///
/// Current GPU state
/// Addresses of the shaders for each stage
/// Compiled graphics shader code
@@ -246,28 +251,25 @@ namespace Ryujinx.Graphics.Gpu.Shader
return null;
}
- QueryInfoCallback queryInfo = (QueryInfoName info, int index) =>
+ int QueryInfo(QueryInfoName info, int index)
{
- switch (info)
+ return info switch
{
- case QueryInfoName.ComputeLocalSizeX:
- return localSizeX;
- case QueryInfoName.ComputeLocalSizeY:
- return localSizeY;
- case QueryInfoName.ComputeLocalSizeZ:
- return localSizeZ;
- case QueryInfoName.ComputeSharedMemorySize:
- return sharedMemorySize;
- }
+ QueryInfoName.ComputeLocalSizeX => localSizeX,
+ QueryInfoName.ComputeLocalSizeY => localSizeY,
+ QueryInfoName.ComputeLocalSizeZ => localSizeZ,
+ QueryInfoName.ComputeSharedMemorySize => sharedMemorySize,
+ _ => QueryInfoCommon(info)
+ };
+ }
- return QueryInfoCommon(info);
- };
+ TranslatorCallbacks callbacks = new TranslatorCallbacks(QueryInfo, PrintLog);
ShaderProgram program;
Span code = _context.MemoryAccessor.Read(gpuVa, MaxProgramSize);
- program = Translator.Translate(code, queryInfo, DefaultFlags | TranslationFlags.Compute);
+ program = Translator.Translate(code, callbacks, DefaultFlags | TranslationFlags.Compute);
int[] codeCached = MemoryMarshal.Cast(code.Slice(0, program.Size)).ToArray();
@@ -284,13 +286,15 @@ namespace Ryujinx.Graphics.Gpu.Shader
///
/// Translates the binary Maxwell shader code to something that the host API accepts.
- /// This will combine the "Vertex A" and "Vertex B" shader stages, if specified, into one shader.
///
+ ///
+ /// This will combine the "Vertex A" and "Vertex B" shader stages, if specified, into one shader.
+ ///
/// Current GPU state
/// Shader stage
/// GPU virtual address of the shader code
/// Optional GPU virtual address of the "Vertex A" shader code
- ///
+ /// Compiled graphics shader code
private CachedShader TranslateGraphicsShader(GpuState state, ShaderStage stage, ulong gpuVa, ulong gpuVaA = 0)
{
if (gpuVa == 0)
@@ -298,20 +302,18 @@ namespace Ryujinx.Graphics.Gpu.Shader
return new CachedShader(null, null);
}
- QueryInfoCallback queryInfo = (QueryInfoName info, int index) =>
+ int QueryInfo(QueryInfoName info, int index)
{
- switch (info)
+ return info switch
{
- case QueryInfoName.IsTextureBuffer:
- return Convert.ToInt32(QueryIsTextureBuffer(state, (int)stage - 1, index));
- case QueryInfoName.IsTextureRectangle:
- return Convert.ToInt32(QueryIsTextureRectangle(state, (int)stage - 1, index));
- case QueryInfoName.PrimitiveTopology:
- return (int)GetPrimitiveTopology();
- }
+ QueryInfoName.IsTextureBuffer => Convert.ToInt32(QueryIsTextureBuffer(state, (int)stage - 1, index)),
+ QueryInfoName.IsTextureRectangle => Convert.ToInt32(QueryIsTextureRectangle(state, (int)stage - 1, index)),
+ QueryInfoName.PrimitiveTopology => (int)GetPrimitiveTopology(),
+ _ => QueryInfoCommon(info)
+ };
+ }
- return QueryInfoCommon(info);
- };
+ TranslatorCallbacks callbacks = new TranslatorCallbacks(QueryInfo, PrintLog);
ShaderProgram program;
@@ -322,7 +324,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
Span codeA = _context.MemoryAccessor.Read(gpuVaA, MaxProgramSize);
Span codeB = _context.MemoryAccessor.Read(gpuVa, MaxProgramSize);
- program = Translator.Translate(codeA, codeB, queryInfo, DefaultFlags);
+ program = Translator.Translate(codeA, codeB, callbacks, DefaultFlags);
// TODO: We should also take "codeA" into account.
codeCached = MemoryMarshal.Cast(codeB.Slice(0, program.Size)).ToArray();
@@ -342,7 +344,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
{
Span code = _context.MemoryAccessor.Read(gpuVa, MaxProgramSize);
- program = Translator.Translate(code, queryInfo, DefaultFlags);
+ program = Translator.Translate(code, callbacks, DefaultFlags);
codeCached = MemoryMarshal.Cast(code.Slice(0, program.Size)).ToArray();
@@ -483,17 +485,21 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// Requested information
private int QueryInfoCommon(QueryInfoName info)
{
- switch (info)
+ return info switch
{
- case QueryInfoName.MaximumViewportDimensions:
- return _context.Capabilities.MaximumViewportDimensions;
- case QueryInfoName.StorageBufferOffsetAlignment:
- return _context.Capabilities.StorageBufferOffsetAlignment;
- case QueryInfoName.SupportsNonConstantTextureOffset:
- return Convert.ToInt32(_context.Capabilities.SupportsNonConstantTextureOffset);
- }
+ QueryInfoName.StorageBufferOffsetAlignment => _context.Capabilities.StorageBufferOffsetAlignment,
+ QueryInfoName.SupportsNonConstantTextureOffset => Convert.ToInt32(_context.Capabilities.SupportsNonConstantTextureOffset),
+ _ => 0
+ };
+ }
- return 0;
+ ///
+ /// Prints a warning from the shader code translator.
+ ///
+ /// Warning message
+ private static void PrintLog(string message)
+ {
+ Logger.PrintWarning(LogClass.Gpu, $"Shader translator: {message}");
}
///
diff --git a/Ryujinx.Graphics.Gpu/State/GpuState.cs b/Ryujinx.Graphics.Gpu/State/GpuState.cs
index 8f851bca5..f673d296c 100644
--- a/Ryujinx.Graphics.Gpu/State/GpuState.cs
+++ b/Ryujinx.Graphics.Gpu/State/GpuState.cs
@@ -187,7 +187,7 @@ namespace Ryujinx.Graphics.Gpu.State
///
/// First register offset
/// Second register offset
- /// Third register offset
+ /// Third register offset
/// True if any register was modified, false otherwise
public bool QueryModified(MethodOffset m1, MethodOffset m2, MethodOffset m3)
{
@@ -207,7 +207,7 @@ namespace Ryujinx.Graphics.Gpu.State
///
/// First register offset
/// Second register offset
- /// Third register offset
+ /// Third register offset
/// Fourth register offset
/// True if any register was modified, false otherwise
public bool QueryModified(MethodOffset m1, MethodOffset m2, MethodOffset m3, MethodOffset m4)
@@ -230,7 +230,7 @@ namespace Ryujinx.Graphics.Gpu.State
///
/// First register offset
/// Second register offset
- /// Third register offset
+ /// Third register offset
/// Fourth register offset
/// Fifth register offset
/// True if any register was modified, false otherwise
diff --git a/Ryujinx.Graphics.Gpu/State/GpuVa.cs b/Ryujinx.Graphics.Gpu/State/GpuVa.cs
index d2ae5eb9e..76a2fddfd 100644
--- a/Ryujinx.Graphics.Gpu/State/GpuVa.cs
+++ b/Ryujinx.Graphics.Gpu/State/GpuVa.cs
@@ -11,7 +11,7 @@ namespace Ryujinx.Graphics.Gpu.State
///
/// Packs the split address into a 64-bits address value.
///
- ///
+ /// The 64-bits address value
public ulong Pack()
{
return Low | ((ulong)High << 32);
diff --git a/Ryujinx.Graphics.Gpu/State/MethodOffset.cs b/Ryujinx.Graphics.Gpu/State/MethodOffset.cs
index ddc17d154..904cf8ff4 100644
--- a/Ryujinx.Graphics.Gpu/State/MethodOffset.cs
+++ b/Ryujinx.Graphics.Gpu/State/MethodOffset.cs
@@ -3,6 +3,9 @@ namespace Ryujinx.Graphics.Gpu.State
///
/// GPU method offset.
///
+ ///
+ /// This is indexed in 32 bits word.
+ ///
enum MethodOffset
{
I2mParams = 0x60,
diff --git a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
index dc147484d..bb8e8339b 100644
--- a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
+++ b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
@@ -7,7 +7,6 @@ namespace Ryujinx.Graphics.OpenGL
{
private static Lazy _supportsAstcCompression = new Lazy(() => HasExtension("GL_KHR_texture_compression_astc_ldr"));
- private static Lazy _maximumViewportDimensions = new Lazy(() => GetLimit(All.MaxViewportDims));
private static Lazy _maximumComputeSharedMemorySize = new Lazy(() => GetLimit(All.MaxComputeSharedMemorySize));
private static Lazy _storageBufferOffsetAlignment = new Lazy(() => GetLimit(All.ShaderStorageBufferOffsetAlignment));
@@ -16,7 +15,6 @@ namespace Ryujinx.Graphics.OpenGL
public static bool SupportsAstcCompression => _supportsAstcCompression.Value;
public static bool SupportsNonConstantTextureOffset => _isNvidiaDriver.Value;
- public static int MaximumViewportDimensions => _maximumViewportDimensions.Value;
public static int MaximumComputeSharedMemorySize => _maximumComputeSharedMemorySize.Value;
public static int StorageBufferOffsetAlignment => _storageBufferOffsetAlignment.Value;
diff --git a/Ryujinx.Graphics.OpenGL/Renderer.cs b/Ryujinx.Graphics.OpenGL/Renderer.cs
index e6021f51f..86ce9c7cd 100644
--- a/Ryujinx.Graphics.OpenGL/Renderer.cs
+++ b/Ryujinx.Graphics.OpenGL/Renderer.cs
@@ -64,7 +64,6 @@ namespace Ryujinx.Graphics.OpenGL
return new Capabilities(
HwCapabilities.SupportsAstcCompression,
HwCapabilities.SupportsNonConstantTextureOffset,
- HwCapabilities.MaximumViewportDimensions,
HwCapabilities.MaximumComputeSharedMemorySize,
HwCapabilities.StorageBufferOffsetAlignment);
}
diff --git a/Ryujinx.Graphics.OpenGL/TextureView.cs b/Ryujinx.Graphics.OpenGL/TextureView.cs
index 563e0ca61..da0872f6d 100644
--- a/Ryujinx.Graphics.OpenGL/TextureView.cs
+++ b/Ryujinx.Graphics.OpenGL/TextureView.cs
@@ -104,6 +104,7 @@ namespace Ryujinx.Graphics.OpenGL
GL.TexParameter(target, TextureParameterName.TextureMaxLevel, maxLevel);
+ // TODO: This requires ARB_stencil_texturing, we should uncomment and test this.
// GL.TexParameter(target, TextureParameterName.DepthStencilTextureMode, (int)_info.DepthStencilMode.Convert());
}
@@ -118,7 +119,11 @@ namespace Ryujinx.Graphics.OpenGL
}
else
{
- // TODO: Improve
+ // TODO: Most graphics APIs doesn't support creating a texture view from a compressed format
+ // with a non-compressed format (or vice-versa), however NVN seems to support it.
+ // So we emulate that here with a texture copy (see the first CopyTo overload).
+ // However right now it only does a single copy right after the view is created,
+ // so it doesn't work for all cases.
TextureView emulatedView = (TextureView)_renderer.CreateTexture(info);
emulatedView._emulatedViewParent = this;
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/CodeGenContext.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/CodeGenContext.cs
index da557cfa8..6bef8e6c2 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/CodeGenContext.cs
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/CodeGenContext.cs
@@ -91,10 +91,5 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
return indentation;
}
-
- public string GetTabString()
- {
- return Tab;
- }
}
}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
index 866df56df..2145920ef 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
@@ -86,6 +86,10 @@ namespace Ryujinx.Graphics.Shader.Instructions
{
context.Barrier();
}
+ else
+ {
+ context.Config.PrintLog($"Invalid barrier mode: {op.Mode}.");
+ }
}
public static void Ipa(EmitterContext context)
@@ -101,8 +105,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
Operand srcA = Attribute(op.AttributeOffset, iq);
- Operand srcB = GetSrcB(context);
-
Operand res = context.FPSaturate(srcA, op.Saturate);
context.Copy(GetDest(context), res);
@@ -128,7 +130,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
if (op.Size > IntegerSize.B64)
{
- // TODO: Warning.
+ context.Config.PrintLog($"Invalid LDC size: {op.Size}.");
}
bool isSmallInt = op.Size < IntegerSize.B32;
@@ -156,7 +158,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
if (isSmallInt)
{
- value = ExtractSmallInt(context, op.Size, wordOffset, value);
+ value = ExtractSmallInt(context, op.Size, bitOffset, value);
}
context.Copy(Register(rd), value);
@@ -261,7 +263,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
}
else
{
- // Not supported or invalid.
+ context.Config.PrintLog($"Invalid reduction type: {type}.");
}
break;
case AtomicOp.BitwiseAnd:
@@ -271,7 +273,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
}
else
{
- // Not supported or invalid.
+ context.Config.PrintLog($"Invalid reduction type: {type}.");
}
break;
case AtomicOp.BitwiseExclusiveOr:
@@ -281,7 +283,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
}
else
{
- // Not supported or invalid.
+ context.Config.PrintLog($"Invalid reduction type: {type}.");
}
break;
case AtomicOp.BitwiseOr:
@@ -291,7 +293,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
}
else
{
- // Not supported or invalid.
+ context.Config.PrintLog($"Invalid reduction type: {type}.");
}
break;
case AtomicOp.Maximum:
@@ -305,7 +307,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
}
else
{
- // Not supported or invalid.
+ context.Config.PrintLog($"Invalid reduction type: {type}.");
}
break;
case AtomicOp.Minimum:
@@ -319,7 +321,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
}
else
{
- // Not supported or invalid.
+ context.Config.PrintLog($"Invalid reduction type: {type}.");
}
break;
}
@@ -333,7 +335,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
if (op.Size > IntegerSize.B128)
{
- // TODO: Warning.
+ context.Config.PrintLog($"Invalid load size: {op.Size}.");
}
bool isSmallInt = op.Size < IntegerSize.B32;
@@ -419,7 +421,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
if (op.Size > IntegerSize.B128)
{
- // TODO: Warning.
+ context.Config.PrintLog($"Invalid store size: {op.Size}.");
}
bool isSmallInt = op.Size < IntegerSize.B32;
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs
index 17e80f4a4..ffc4c430f 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitMove.cs
@@ -11,8 +11,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
{
public static void Mov(EmitterContext context)
{
- OpCodeAlu op = (OpCodeAlu)context.CurrOp;
-
context.Copy(GetDest(context), GetSrcB(context));
}
@@ -33,7 +31,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
if (isCC)
{
- // TODO.
+ // TODO: Support Register to condition code flags copy.
+ context.Config.PrintLog("R2P.CC not implemented.");
}
else
{
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
index 59096869e..7b9794eaf 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
@@ -18,7 +18,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
if (type == SamplerType.None)
{
- // TODO: Error, encoding is invalid.
+ context.Config.PrintLog("Invalid image store sampler type.");
return;
}
@@ -86,7 +86,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
}
else
{
- // TODO.
+ context.Config.PrintLog("Unsized image store not supported.");
}
Operand[] sources = sourcesList.ToArray();
@@ -180,7 +180,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
if (type == SamplerType.None)
{
- // TODO: Error, encoding is invalid.
+ context.Config.PrintLog("Invalid texture sampler type.");
return;
}
@@ -210,40 +210,40 @@ namespace Ryujinx.Graphics.Shader.Instructions
{
switch (texsOp.Target)
{
- case Decoders.TextureTarget.Texture1DLodZero:
+ case TextureTarget.Texture1DLodZero:
sourcesList.Add(Ra());
break;
- case Decoders.TextureTarget.Texture2D:
+ case TextureTarget.Texture2D:
sourcesList.Add(Ra());
sourcesList.Add(Rb());
break;
- case Decoders.TextureTarget.Texture2DLodZero:
+ case TextureTarget.Texture2DLodZero:
sourcesList.Add(Ra());
sourcesList.Add(Rb());
sourcesList.Add(ConstF(0));
break;
- case Decoders.TextureTarget.Texture2DLodLevel:
- case Decoders.TextureTarget.Texture2DDepthCompare:
- case Decoders.TextureTarget.Texture3D:
- case Decoders.TextureTarget.TextureCube:
+ case TextureTarget.Texture2DLodLevel:
+ case TextureTarget.Texture2DDepthCompare:
+ case TextureTarget.Texture3D:
+ case TextureTarget.TextureCube:
sourcesList.Add(Ra());
sourcesList.Add(Ra());
sourcesList.Add(Rb());
break;
- case Decoders.TextureTarget.Texture2DLodZeroDepthCompare:
- case Decoders.TextureTarget.Texture3DLodZero:
+ case TextureTarget.Texture2DLodZeroDepthCompare:
+ case TextureTarget.Texture3DLodZero:
sourcesList.Add(Ra());
sourcesList.Add(Ra());
sourcesList.Add(Rb());
sourcesList.Add(ConstF(0));
break;
- case Decoders.TextureTarget.Texture2DLodLevelDepthCompare:
- case Decoders.TextureTarget.TextureCubeLodLevel:
+ case TextureTarget.Texture2DLodLevelDepthCompare:
+ case TextureTarget.TextureCubeLodLevel:
sourcesList.Add(Ra());
sourcesList.Add(Ra());
sourcesList.Add(Rb());
@@ -258,7 +258,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
if (type == SamplerType.None)
{
- // TODO: Error, encoding is invalid.
+ context.Config.PrintLog("Invalid texel fetch sampler type.");
return;
}
@@ -742,8 +742,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
{
OpCodeTexture op = (OpCodeTexture)context.CurrOp;
- bool isBindless = (flags & TextureFlags.Bindless) != 0;
- bool intCoords = (flags & TextureFlags.IntCoords) != 0;
+ bool isBindless = (flags & TextureFlags.Bindless) != 0;
if (op.Rd.IsRZ)
{
@@ -920,36 +919,36 @@ namespace Ryujinx.Graphics.Shader.Instructions
throw new ArgumentException($"Invalid texture dimensions \"{dimensions}\".");
}
- private static SamplerType ConvertSamplerType(Decoders.TextureTarget type)
+ private static SamplerType ConvertSamplerType(TextureTarget type)
{
switch (type)
{
- case Decoders.TextureTarget.Texture1DLodZero:
+ case TextureTarget.Texture1DLodZero:
return SamplerType.Texture1D;
- case Decoders.TextureTarget.Texture2D:
- case Decoders.TextureTarget.Texture2DLodZero:
- case Decoders.TextureTarget.Texture2DLodLevel:
+ case TextureTarget.Texture2D:
+ case TextureTarget.Texture2DLodZero:
+ case TextureTarget.Texture2DLodLevel:
return SamplerType.Texture2D;
- case Decoders.TextureTarget.Texture2DDepthCompare:
- case Decoders.TextureTarget.Texture2DLodLevelDepthCompare:
- case Decoders.TextureTarget.Texture2DLodZeroDepthCompare:
+ case TextureTarget.Texture2DDepthCompare:
+ case TextureTarget.Texture2DLodLevelDepthCompare:
+ case TextureTarget.Texture2DLodZeroDepthCompare:
return SamplerType.Texture2D | SamplerType.Shadow;
- case Decoders.TextureTarget.Texture2DArray:
- case Decoders.TextureTarget.Texture2DArrayLodZero:
+ case TextureTarget.Texture2DArray:
+ case TextureTarget.Texture2DArrayLodZero:
return SamplerType.Texture2D | SamplerType.Array;
- case Decoders.TextureTarget.Texture2DArrayLodZeroDepthCompare:
+ case TextureTarget.Texture2DArrayLodZeroDepthCompare:
return SamplerType.Texture2D | SamplerType.Array | SamplerType.Shadow;
- case Decoders.TextureTarget.Texture3D:
- case Decoders.TextureTarget.Texture3DLodZero:
+ case TextureTarget.Texture3D:
+ case TextureTarget.Texture3DLodZero:
return SamplerType.Texture3D;
- case Decoders.TextureTarget.TextureCube:
- case Decoders.TextureTarget.TextureCubeLodLevel:
+ case TextureTarget.TextureCube:
+ case TextureTarget.TextureCubeLodLevel:
return SamplerType.TextureCube;
}
@@ -987,22 +986,22 @@ namespace Ryujinx.Graphics.Shader.Instructions
{
switch (type)
{
- case Decoders.TextureTarget.Texture1DLodZero:
- case Decoders.TextureTarget.Texture2DLodZero:
- case Decoders.TextureTarget.Texture2DLodLevel:
- case Decoders.TextureTarget.Texture2DLodLevelDepthCompare:
- case Decoders.TextureTarget.Texture2DLodZeroDepthCompare:
- case Decoders.TextureTarget.Texture2DArrayLodZero:
- case Decoders.TextureTarget.Texture2DArrayLodZeroDepthCompare:
- case Decoders.TextureTarget.Texture3DLodZero:
- case Decoders.TextureTarget.TextureCubeLodLevel:
+ case TextureTarget.Texture1DLodZero:
+ case TextureTarget.Texture2DLodZero:
+ case TextureTarget.Texture2DLodLevel:
+ case TextureTarget.Texture2DLodLevelDepthCompare:
+ case TextureTarget.Texture2DLodZeroDepthCompare:
+ case TextureTarget.Texture2DArrayLodZero:
+ case TextureTarget.Texture2DArrayLodZeroDepthCompare:
+ case TextureTarget.Texture3DLodZero:
+ case TextureTarget.TextureCubeLodLevel:
return TextureFlags.LodLevel;
- case Decoders.TextureTarget.Texture2D:
- case Decoders.TextureTarget.Texture2DDepthCompare:
- case Decoders.TextureTarget.Texture2DArray:
- case Decoders.TextureTarget.Texture3D:
- case Decoders.TextureTarget.TextureCube:
+ case TextureTarget.Texture2D:
+ case TextureTarget.Texture2DDepthCompare:
+ case TextureTarget.Texture2DArray:
+ case TextureTarget.Texture3D:
+ case TextureTarget.TextureCube:
return TextureFlags.None;
}
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitVote.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitVote.cs
index 9c4d5f1af..8f81ecb4d 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitVote.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitVote.cs
@@ -36,7 +36,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
}
else
{
- // Invalid.
+ context.Config.PrintLog($"Invalid vote operation: {op.VoteOp}.");
}
if (!op.Rd.IsRZ)
diff --git a/Ryujinx.Graphics.Shader/QueryInfoCallback.cs b/Ryujinx.Graphics.Shader/QueryInfoCallback.cs
deleted file mode 100644
index 28261a77e..000000000
--- a/Ryujinx.Graphics.Shader/QueryInfoCallback.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace Ryujinx.Graphics.Shader
-{
- public delegate int QueryInfoCallback(QueryInfoName info, int index);
-}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/QueryInfoName.cs b/Ryujinx.Graphics.Shader/QueryInfoName.cs
index 1d87c2c88..c4f2cb6cc 100644
--- a/Ryujinx.Graphics.Shader/QueryInfoName.cs
+++ b/Ryujinx.Graphics.Shader/QueryInfoName.cs
@@ -8,7 +8,6 @@ namespace Ryujinx.Graphics.Shader
ComputeSharedMemorySize,
IsTextureBuffer,
IsTextureRectangle,
- MaximumViewportDimensions,
PrimitiveTopology,
StorageBufferOffsetAlignment,
SupportsNonConstantTextureOffset
diff --git a/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs b/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs
index e6334feaf..fbe197651 100644
--- a/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs
+++ b/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs
@@ -13,6 +13,8 @@ namespace Ryujinx.Graphics.Shader.Translation
private ShaderConfig _config;
+ public ShaderConfig Config => _config;
+
private List _operations;
private Dictionary _labels;
diff --git a/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs b/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
index d73a268e9..8a0f25fe4 100644
--- a/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
+++ b/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
@@ -16,30 +16,30 @@ namespace Ryujinx.Graphics.Shader.Translation
public TranslationFlags Flags { get; }
- private QueryInfoCallback _queryInfoCallback;
+ private TranslatorCallbacks _callbacks;
- public ShaderConfig(TranslationFlags flags, QueryInfoCallback queryInfoCallback)
+ public ShaderConfig(TranslationFlags flags, TranslatorCallbacks callbacks)
{
- Stage = ShaderStage.Compute;
- OutputTopology = OutputTopology.PointList;
- MaxOutputVertices = 0;
- OmapTargets = null;
- OmapSampleMask = false;
- OmapDepth = false;
- Flags = flags;
- _queryInfoCallback = queryInfoCallback;
+ Stage = ShaderStage.Compute;
+ OutputTopology = OutputTopology.PointList;
+ MaxOutputVertices = 0;
+ OmapTargets = null;
+ OmapSampleMask = false;
+ OmapDepth = false;
+ Flags = flags;
+ _callbacks = callbacks;
}
- public ShaderConfig(ShaderHeader header, TranslationFlags flags, QueryInfoCallback queryInfoCallback)
+ public ShaderConfig(ShaderHeader header, TranslationFlags flags, TranslatorCallbacks callbacks)
{
- Stage = header.Stage;
- OutputTopology = header.OutputTopology;
- MaxOutputVertices = header.MaxOutputVertexCount;
- OmapTargets = header.OmapTargets;
- OmapSampleMask = header.OmapSampleMask;
- OmapDepth = header.OmapDepth;
- Flags = flags;
- _queryInfoCallback = queryInfoCallback;
+ Stage = header.Stage;
+ OutputTopology = header.OutputTopology;
+ MaxOutputVertices = header.MaxOutputVertexCount;
+ OmapTargets = header.OmapTargets;
+ OmapSampleMask = header.OmapSampleMask;
+ OmapDepth = header.OmapDepth;
+ Flags = flags;
+ _callbacks = callbacks;
}
public int GetDepthRegister()
@@ -68,9 +68,9 @@ namespace Ryujinx.Graphics.Shader.Translation
public int QueryInfo(QueryInfoName info, int index = 0)
{
- if (_queryInfoCallback != null)
+ if (_callbacks.QueryInfo != null)
{
- return _queryInfoCallback(info, index);
+ return _callbacks.QueryInfo(info, index);
}
else
{
@@ -86,8 +86,6 @@ namespace Ryujinx.Graphics.Shader.Translation
return Convert.ToInt32(false);
case QueryInfoName.IsTextureRectangle:
return Convert.ToInt32(false);
- case QueryInfoName.MaximumViewportDimensions:
- return 0x8000;
case QueryInfoName.PrimitiveTopology:
return (int)InputTopology.Points;
case QueryInfoName.StorageBufferOffsetAlignment:
@@ -99,5 +97,10 @@ namespace Ryujinx.Graphics.Shader.Translation
return 0;
}
+
+ public void PrintLog(string message)
+ {
+ _callbacks.PrintLog?.Invoke(message);
+ }
}
}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Translation/Translator.cs b/Ryujinx.Graphics.Shader/Translation/Translator.cs
index af209edf1..bdc6a094f 100644
--- a/Ryujinx.Graphics.Shader/Translation/Translator.cs
+++ b/Ryujinx.Graphics.Shader/Translation/Translator.cs
@@ -40,21 +40,17 @@ namespace Ryujinx.Graphics.Shader.Translation
return code.Slice(0, headerSize + (int)endAddress);
}
- public static ShaderProgram Translate(Span code, QueryInfoCallback queryInfoCallback, TranslationFlags flags)
+ public static ShaderProgram Translate(Span code, TranslatorCallbacks callbacks, TranslationFlags flags)
{
- bool compute = (flags & TranslationFlags.Compute) != 0;
-
- Operation[] ops = DecodeShader(code, queryInfoCallback, flags, out ShaderConfig config, out int size);
+ Operation[] ops = DecodeShader(code, callbacks, flags, out ShaderConfig config, out int size);
return Translate(ops, config, size);
}
- public static ShaderProgram Translate(Span vpACode, Span vpBCode, QueryInfoCallback queryInfoCallback, TranslationFlags flags)
+ public static ShaderProgram Translate(Span vpACode, Span vpBCode, TranslatorCallbacks callbacks, TranslationFlags flags)
{
- bool debugMode = (flags & TranslationFlags.DebugMode) != 0;
-
- Operation[] vpAOps = DecodeShader(vpACode, queryInfoCallback, flags, out _, out _);
- Operation[] vpBOps = DecodeShader(vpBCode, queryInfoCallback, flags, out ShaderConfig config, out int sizeB);
+ Operation[] vpAOps = DecodeShader(vpACode, callbacks, flags, out _, out _);
+ Operation[] vpBOps = DecodeShader(vpBCode, callbacks, flags, out ShaderConfig config, out int sizeB);
return Translate(Combine(vpAOps, vpBOps), config, sizeB);
}
@@ -94,34 +90,34 @@ namespace Ryujinx.Graphics.Shader.Translation
}
private static Operation[] DecodeShader(
- Span code,
- QueryInfoCallback queryInfoCallback,
- TranslationFlags flags,
- out ShaderConfig config,
- out int size)
+ Span code,
+ TranslatorCallbacks callbacks,
+ TranslationFlags flags,
+ out ShaderConfig config,
+ out int size)
{
Block[] cfg;
if ((flags & TranslationFlags.Compute) != 0)
{
- config = new ShaderConfig(flags, queryInfoCallback);
+ config = new ShaderConfig(flags, callbacks);
cfg = Decoder.Decode(code, 0);
}
else
{
- config = new ShaderConfig(new ShaderHeader(code), flags, queryInfoCallback);
+ config = new ShaderConfig(new ShaderHeader(code), flags, callbacks);
cfg = Decoder.Decode(code, HeaderSize);
}
if (cfg == null)
{
- // TODO: Error.
+ config.PrintLog("Invalid branch detected, failed to build CFG.");
size = 0;
- return new Operation[0];
+ return Array.Empty();
}
EmitterContext context = new EmitterContext(config);
@@ -156,6 +152,8 @@ namespace Ryujinx.Graphics.Shader.Translation
else
{
instName = "???";
+
+ config.PrintLog($"Invalid instruction at 0x{op.Address:X6} (0x{op.RawOpCode:X16}).");
}
string dbgComment = $"0x{op.Address:X6}: 0x{op.RawOpCode:X16} {instName}";
@@ -210,10 +208,7 @@ namespace Ryujinx.Graphics.Shader.Translation
context.CurrOp = op;
- if (op.Emitter != null)
- {
- op.Emitter(context);
- }
+ op.Emitter?.Invoke(context);
if (predSkipLbl != null)
{
diff --git a/Ryujinx.Graphics.Shader/Translation/TranslatorCallbacks.cs b/Ryujinx.Graphics.Shader/Translation/TranslatorCallbacks.cs
new file mode 100644
index 000000000..e0e9852fa
--- /dev/null
+++ b/Ryujinx.Graphics.Shader/Translation/TranslatorCallbacks.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace Ryujinx.Graphics.Shader.Translation
+{
+ public struct TranslatorCallbacks
+ {
+ internal Func QueryInfo { get; }
+
+ internal Action PrintLog { get; }
+
+ public TranslatorCallbacks(Func queryInfoCallback, Action printLogCallback)
+ {
+ QueryInfo = queryInfoCallback;
+ PrintLog = printLogCallback;
+ }
+ }
+}
diff --git a/Ryujinx/Ui/MainWindow.cs b/Ryujinx/Ui/MainWindow.cs
index 69c5364b4..2c4d01126 100644
--- a/Ryujinx/Ui/MainWindow.cs
+++ b/Ryujinx/Ui/MainWindow.cs
@@ -405,14 +405,14 @@ namespace Ryujinx.Ui
/// An supported by this machine
private static IAalOutput InitializeAudioEngine()
{
- /*if (SoundIoAudioOut.IsSupported)
- {
- return new SoundIoAudioOut();
- }
- else*/ if (OpenALAudioOut.IsSupported)
+ if (OpenALAudioOut.IsSupported)
{
return new OpenALAudioOut();
}
+ else if (SoundIoAudioOut.IsSupported)
+ {
+ return new SoundIoAudioOut();
+ }
else
{
return new DummyAudioOut();