Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7d158acc3b | ||
|
5dbba07e33 | ||
|
d86249cb0a | ||
|
04d68ca616 | ||
|
050f22977f | ||
|
319507f2a1 | ||
|
d717aef2be | ||
|
24ee8c39f1 |
4
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
4
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -23,7 +23,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Log file
|
label: Log file
|
||||||
description: A log file will help our developers to better diagnose and fix the issue.
|
description: A log file will help our developers to better diagnose and fix the issue.
|
||||||
placeholder: Logs files can be found under "Logs" folder in Ryujinx program folder. You can drag and drop the log on to the text area
|
placeholder: Logs files can be found under "Logs" folder in Ryujinx program folder. They can also be accessed by opening Ryujinx, then going to File > Open Logs Folder. You can drag and drop the log on to the text area (do not copy paste).
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: input
|
- type: input
|
||||||
@ -83,4 +83,4 @@ body:
|
|||||||
- Additional info about your environment:
|
- Additional info about your environment:
|
||||||
- Any other information relevant to your issue.
|
- Any other information relevant to your issue.
|
||||||
validations:
|
validations:
|
||||||
required: false
|
required: false
|
||||||
|
@ -71,6 +71,8 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
|
|
||||||
public readonly int GatherBiasPrecision;
|
public readonly int GatherBiasPrecision;
|
||||||
|
|
||||||
|
public readonly ulong MaximumGpuMemory;
|
||||||
|
|
||||||
public Capabilities(
|
public Capabilities(
|
||||||
TargetApi api,
|
TargetApi api,
|
||||||
string vendorName,
|
string vendorName,
|
||||||
@ -131,7 +133,8 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
int shaderSubgroupSize,
|
int shaderSubgroupSize,
|
||||||
int storageBufferOffsetAlignment,
|
int storageBufferOffsetAlignment,
|
||||||
int textureBufferOffsetAlignment,
|
int textureBufferOffsetAlignment,
|
||||||
int gatherBiasPrecision)
|
int gatherBiasPrecision,
|
||||||
|
ulong maximumGpuMemory)
|
||||||
{
|
{
|
||||||
Api = api;
|
Api = api;
|
||||||
VendorName = vendorName;
|
VendorName = vendorName;
|
||||||
@ -193,6 +196,7 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
StorageBufferOffsetAlignment = storageBufferOffsetAlignment;
|
StorageBufferOffsetAlignment = storageBufferOffsetAlignment;
|
||||||
TextureBufferOffsetAlignment = textureBufferOffsetAlignment;
|
TextureBufferOffsetAlignment = textureBufferOffsetAlignment;
|
||||||
GatherBiasPrecision = gatherBiasPrecision;
|
GatherBiasPrecision = gatherBiasPrecision;
|
||||||
|
MaximumGpuMemory = maximumGpuMemory;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
@ -46,7 +47,11 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
{
|
{
|
||||||
private const int MinCountForDeletion = 32;
|
private const int MinCountForDeletion = 32;
|
||||||
private const int MaxCapacity = 2048;
|
private const int MaxCapacity = 2048;
|
||||||
private const ulong MaxTextureSizeCapacity = 1024 * 1024 * 1024; // MB;
|
private const ulong MinTextureSizeCapacity = 512 * 1024 * 1024;
|
||||||
|
private const ulong MaxTextureSizeCapacity = 4UL * 1024 * 1024 * 1024;
|
||||||
|
private const ulong DefaultTextureSizeCapacity = 1UL * 1024 * 1024 * 1024;
|
||||||
|
private const float MemoryScaleFactor = 0.50f;
|
||||||
|
private ulong _maxCacheMemoryUsage = 0;
|
||||||
|
|
||||||
private readonly LinkedList<Texture> _textures;
|
private readonly LinkedList<Texture> _textures;
|
||||||
private ulong _totalSize;
|
private ulong _totalSize;
|
||||||
@ -56,6 +61,25 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
|
|
||||||
private readonly Dictionary<TextureDescriptor, ShortTextureCacheEntry> _shortCacheLookup;
|
private readonly Dictionary<TextureDescriptor, ShortTextureCacheEntry> _shortCacheLookup;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the cache, setting the maximum texture capacity for the specified GPU context.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If the backend GPU has 0 memory capacity, the cache size defaults to `DefaultTextureSizeCapacity`.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="context">The GPU context that the cache belongs to</param>
|
||||||
|
public void Initialize(GpuContext context)
|
||||||
|
{
|
||||||
|
var cacheMemory = (ulong)(context.Capabilities.MaximumGpuMemory * MemoryScaleFactor);
|
||||||
|
|
||||||
|
_maxCacheMemoryUsage = Math.Clamp(cacheMemory, MinTextureSizeCapacity, MaxTextureSizeCapacity);
|
||||||
|
|
||||||
|
if (context.Capabilities.MaximumGpuMemory == 0)
|
||||||
|
{
|
||||||
|
_maxCacheMemoryUsage = DefaultTextureSizeCapacity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of the automatic deletion cache.
|
/// Creates a new instance of the automatic deletion cache.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -85,7 +109,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
texture.CacheNode = _textures.AddLast(texture);
|
texture.CacheNode = _textures.AddLast(texture);
|
||||||
|
|
||||||
if (_textures.Count > MaxCapacity ||
|
if (_textures.Count > MaxCapacity ||
|
||||||
(_totalSize > MaxTextureSizeCapacity && _textures.Count >= MinCountForDeletion))
|
(_totalSize > _maxCacheMemoryUsage && _textures.Count >= MinCountForDeletion))
|
||||||
{
|
{
|
||||||
RemoveLeastUsedTexture();
|
RemoveLeastUsedTexture();
|
||||||
}
|
}
|
||||||
@ -110,7 +134,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
_textures.AddLast(texture.CacheNode);
|
_textures.AddLast(texture.CacheNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_totalSize > MaxTextureSizeCapacity && _textures.Count >= MinCountForDeletion)
|
if (_totalSize > _maxCacheMemoryUsage && _textures.Count >= MinCountForDeletion)
|
||||||
{
|
{
|
||||||
RemoveLeastUsedTexture();
|
RemoveLeastUsedTexture();
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,11 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsDisposed { get; private set; }
|
public bool IsDisposed { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// True if the sampler has sRGB conversion enabled, false otherwise.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsSrgb { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Host sampler object.
|
/// Host sampler object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -30,6 +35,8 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
/// <param name="descriptor">The Maxwell sampler descriptor</param>
|
/// <param name="descriptor">The Maxwell sampler descriptor</param>
|
||||||
public Sampler(GpuContext context, SamplerDescriptor descriptor)
|
public Sampler(GpuContext context, SamplerDescriptor descriptor)
|
||||||
{
|
{
|
||||||
|
IsSrgb = descriptor.UnpackSrgb();
|
||||||
|
|
||||||
MinFilter minFilter = descriptor.UnpackMinFilter();
|
MinFilter minFilter = descriptor.UnpackMinFilter();
|
||||||
MagFilter magFilter = descriptor.UnpackMagFilter();
|
MagFilter magFilter = descriptor.UnpackMagFilter();
|
||||||
|
|
||||||
|
@ -113,6 +113,15 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
return (CompareOp)(((Word0 >> 10) & 7) + 1);
|
return (CompareOp)(((Word0 >> 10) & 7) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unpacks the sampler sRGB format flag.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if the has sampler is sRGB conversion enabled, false otherwise</returns>
|
||||||
|
public readonly bool UnpackSrgb()
|
||||||
|
{
|
||||||
|
return (Word0 & (1 << 13)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unpacks and converts the maximum anisotropy value used for texture anisotropic filtering.
|
/// Unpacks and converts the maximum anisotropy value used for texture anisotropic filtering.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -187,7 +187,9 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
{
|
{
|
||||||
(TexturePool texturePool, SamplerPool samplerPool) = GetPools();
|
(TexturePool texturePool, SamplerPool samplerPool) = GetPools();
|
||||||
|
|
||||||
return (texturePool.Get(textureId), samplerPool.Get(samplerId));
|
Sampler sampler = samplerPool?.Get(samplerId);
|
||||||
|
|
||||||
|
return (texturePool.Get(textureId, sampler?.IsSrgb ?? true), sampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -508,12 +510,12 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
state.TextureHandle = textureId;
|
state.TextureHandle = textureId;
|
||||||
state.SamplerHandle = samplerId;
|
state.SamplerHandle = samplerId;
|
||||||
|
|
||||||
ref readonly TextureDescriptor descriptor = ref texturePool.GetForBinding(textureId, out Texture texture);
|
Sampler sampler = samplerPool?.Get(samplerId);
|
||||||
|
|
||||||
|
ref readonly TextureDescriptor descriptor = ref texturePool.GetForBinding(textureId, sampler?.IsSrgb ?? true, out Texture texture);
|
||||||
|
|
||||||
specStateMatches &= specState.MatchesTexture(stage, index, descriptor);
|
specStateMatches &= specState.MatchesTexture(stage, index, descriptor);
|
||||||
|
|
||||||
Sampler sampler = samplerPool?.Get(samplerId);
|
|
||||||
|
|
||||||
ITexture hostTexture = texture?.GetTargetTexture(bindingInfo.Target);
|
ITexture hostTexture = texture?.GetTargetTexture(bindingInfo.Target);
|
||||||
ISampler hostSampler = sampler?.GetHostSampler(texture);
|
ISampler hostSampler = sampler?.GetHostSampler(texture);
|
||||||
|
|
||||||
|
@ -68,6 +68,14 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
_cache = new AutoDeleteCache();
|
_cache = new AutoDeleteCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the cache, setting the maximum texture capacity for the specified GPU context.
|
||||||
|
/// </summary>
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
_cache.Initialize(_context);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handles marking of textures written to a memory region being (partially) remapped.
|
/// Handles marking of textures written to a memory region being (partially) remapped.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -227,6 +227,17 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
/// <param name="id">ID of the texture. This is effectively a zero-based index</param>
|
/// <param name="id">ID of the texture. This is effectively a zero-based index</param>
|
||||||
/// <returns>The texture with the given ID</returns>
|
/// <returns>The texture with the given ID</returns>
|
||||||
public override Texture Get(int id)
|
public override Texture Get(int id)
|
||||||
|
{
|
||||||
|
return Get(id, srgbSampler: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the texture with the given ID.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">ID of the texture. This is effectively a zero-based index</param>
|
||||||
|
/// <param name="srgbSampler">Whether the texture is being accessed with a sampler that has sRGB conversion enabled</param>
|
||||||
|
/// <returns>The texture with the given ID</returns>
|
||||||
|
public Texture Get(int id, bool srgbSampler)
|
||||||
{
|
{
|
||||||
if ((uint)id >= Items.Length)
|
if ((uint)id >= Items.Length)
|
||||||
{
|
{
|
||||||
@ -240,7 +251,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
SynchronizeMemory();
|
SynchronizeMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
GetInternal(id, out Texture texture);
|
GetForBinding(id, srgbSampler, out Texture texture);
|
||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
@ -252,9 +263,10 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
/// This method assumes that the pool has been manually synchronized before doing binding.
|
/// This method assumes that the pool has been manually synchronized before doing binding.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="id">ID of the texture. This is effectively a zero-based index</param>
|
/// <param name="id">ID of the texture. This is effectively a zero-based index</param>
|
||||||
|
/// <param name="srgbSampler">Whether the texture is being accessed with a sampler that has sRGB conversion enabled</param>
|
||||||
/// <param name="texture">The texture with the given ID</param>
|
/// <param name="texture">The texture with the given ID</param>
|
||||||
/// <returns>The texture descriptor with the given ID</returns>
|
/// <returns>The texture descriptor with the given ID</returns>
|
||||||
public ref readonly TextureDescriptor GetForBinding(int id, out Texture texture)
|
public ref readonly TextureDescriptor GetForBinding(int id, bool srgbSampler, out Texture texture)
|
||||||
{
|
{
|
||||||
if ((uint)id >= Items.Length)
|
if ((uint)id >= Items.Length)
|
||||||
{
|
{
|
||||||
@ -264,6 +276,18 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
|
|
||||||
// When getting for binding, assume the pool has already been synchronized.
|
// When getting for binding, assume the pool has already been synchronized.
|
||||||
|
|
||||||
|
if (!srgbSampler)
|
||||||
|
{
|
||||||
|
// If the sampler does not have the sRGB bit enabled, then the texture can't use a sRGB format.
|
||||||
|
ref readonly TextureDescriptor tempDescriptor = ref GetDescriptorRef(id);
|
||||||
|
|
||||||
|
if (tempDescriptor.UnpackSrgb() && FormatTable.TryGetTextureFormat(tempDescriptor.UnpackFormat(), isSrgb: false, out FormatInfo formatInfo))
|
||||||
|
{
|
||||||
|
// Get a view of the texture with the right format.
|
||||||
|
return ref GetForBinding(id, formatInfo, out texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ref GetInternal(id, out texture);
|
return ref GetInternal(id, out texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
|
using Ryujinx.Graphics.Gpu.Image;
|
||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using Ryujinx.Memory.Range;
|
using Ryujinx.Memory.Range;
|
||||||
using System;
|
using System;
|
||||||
@ -64,6 +65,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
MemoryUnmapped += Physical.BufferCache.MemoryUnmappedHandler;
|
MemoryUnmapped += Physical.BufferCache.MemoryUnmappedHandler;
|
||||||
MemoryUnmapped += VirtualRangeCache.MemoryUnmappedHandler;
|
MemoryUnmapped += VirtualRangeCache.MemoryUnmappedHandler;
|
||||||
MemoryUnmapped += CounterCache.MemoryUnmappedHandler;
|
MemoryUnmapped += CounterCache.MemoryUnmappedHandler;
|
||||||
|
Physical.TextureCache.Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -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 = 7320;
|
private const uint CodeGenVersion = 7353;
|
||||||
|
|
||||||
private const string SharedTocFileName = "shared.toc";
|
private const string SharedTocFileName = "shared.toc";
|
||||||
private const string SharedDataFileName = "shared.data";
|
private const string SharedDataFileName = "shared.data";
|
||||||
|
@ -743,7 +743,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
constantBufferUsePerStageMask &= ~(1 << index);
|
constantBufferUsePerStageMask &= ~(1 << index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkTextures)
|
if (checkTextures && _allTextures.Length > 0)
|
||||||
{
|
{
|
||||||
TexturePool pool = channel.TextureManager.GetTexturePool(poolState.TexturePoolGpuVa, poolState.TexturePoolMaximumId);
|
TexturePool pool = channel.TextureManager.GetTexturePool(poolState.TexturePoolGpuVa, poolState.TexturePoolMaximumId);
|
||||||
|
|
||||||
|
@ -202,7 +202,8 @@ namespace Ryujinx.Graphics.OpenGL
|
|||||||
shaderSubgroupSize: Constants.MaxSubgroupSize,
|
shaderSubgroupSize: Constants.MaxSubgroupSize,
|
||||||
storageBufferOffsetAlignment: HwCapabilities.StorageBufferOffsetAlignment,
|
storageBufferOffsetAlignment: HwCapabilities.StorageBufferOffsetAlignment,
|
||||||
textureBufferOffsetAlignment: HwCapabilities.TextureBufferOffsetAlignment,
|
textureBufferOffsetAlignment: HwCapabilities.TextureBufferOffsetAlignment,
|
||||||
gatherBiasPrecision: intelWindows || amdWindows ? 8 : 0); // Precision is 8 for these vendors on Vulkan.
|
gatherBiasPrecision: intelWindows || amdWindows ? 8 : 0, // Precision is 8 for these vendors on Vulkan.
|
||||||
|
maximumGpuMemory: 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetBufferData(BufferHandle buffer, int offset, ReadOnlySpan<byte> data)
|
public void SetBufferData(BufferHandle buffer, int offset, ReadOnlySpan<byte> data)
|
||||||
|
@ -138,6 +138,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||||||
// Ensure that conditions met for that branch are also met for the current one.
|
// Ensure that conditions met for that branch are also met for the current one.
|
||||||
// Prefer the latest sources for the phi node.
|
// Prefer the latest sources for the phi node.
|
||||||
|
|
||||||
|
int undefCount = 0;
|
||||||
|
|
||||||
for (int i = phiNode.SourcesCount - 1; i >= 0; i--)
|
for (int i = phiNode.SourcesCount - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
BasicBlock phiBlock = phiNode.GetBlock(i);
|
BasicBlock phiBlock = phiNode.GetBlock(i);
|
||||||
@ -159,6 +161,26 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (phiSource.Type == OperandType.Undefined)
|
||||||
|
{
|
||||||
|
undefCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If all sources but one are undefined, we can assume that the one
|
||||||
|
// that is not undefined is the right one.
|
||||||
|
|
||||||
|
if (undefCount == phiNode.SourcesCount - 1)
|
||||||
|
{
|
||||||
|
for (int i = phiNode.SourcesCount - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
Operand phiSource = phiNode.GetSource(i);
|
||||||
|
|
||||||
|
if (phiSource.Type != OperandType.Undefined)
|
||||||
|
{
|
||||||
|
return phiSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
|
|
||||||
if (stage == ShaderStage.Vertex)
|
if (stage == ShaderStage.Vertex)
|
||||||
{
|
{
|
||||||
InitializePositionOutput(context);
|
InitializeVertexOutputs(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt128 usedAttributes = context.TranslatorContext.AttributeUsage.NextInputAttributesComponents;
|
UInt128 usedAttributes = context.TranslatorContext.AttributeUsage.NextInputAttributesComponents;
|
||||||
@ -236,12 +236,20 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void InitializePositionOutput(EmitterContext context)
|
private static void InitializeVertexOutputs(EmitterContext context)
|
||||||
{
|
{
|
||||||
for (int c = 0; c < 4; c++)
|
for (int c = 0; c < 4; c++)
|
||||||
{
|
{
|
||||||
context.Store(StorageKind.Output, IoVariable.Position, null, Const(c), ConstF(c == 3 ? 1f : 0f));
|
context.Store(StorageKind.Output, IoVariable.Position, null, Const(c), ConstF(c == 3 ? 1f : 0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context.Program.ClipDistancesWritten != 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
context.Store(StorageKind.Output, IoVariable.ClipDistance, null, Const(i), ConstF(0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void InitializeOutput(EmitterContext context, int location, bool perPatch)
|
private static void InitializeOutput(EmitterContext context, int location, bool perPatch)
|
||||||
|
@ -636,9 +636,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
var oldStencilTestEnable = _newState.StencilTestEnable;
|
var oldStencilTestEnable = _newState.StencilTestEnable;
|
||||||
var oldDepthTestEnable = _newState.DepthTestEnable;
|
var oldDepthTestEnable = _newState.DepthTestEnable;
|
||||||
var oldDepthWriteEnable = _newState.DepthWriteEnable;
|
var oldDepthWriteEnable = _newState.DepthWriteEnable;
|
||||||
var oldTopology = _newState.Topology;
|
|
||||||
var oldViewports = DynamicState.Viewports;
|
var oldViewports = DynamicState.Viewports;
|
||||||
var oldViewportsCount = _newState.ViewportsCount;
|
var oldViewportsCount = _newState.ViewportsCount;
|
||||||
|
var oldTopology = _topology;
|
||||||
|
|
||||||
_newState.CullMode = CullModeFlags.None;
|
_newState.CullMode = CullModeFlags.None;
|
||||||
_newState.StencilTestEnable = false;
|
_newState.StencilTestEnable = false;
|
||||||
@ -658,7 +658,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_newState.StencilTestEnable = oldStencilTestEnable;
|
_newState.StencilTestEnable = oldStencilTestEnable;
|
||||||
_newState.DepthTestEnable = oldDepthTestEnable;
|
_newState.DepthTestEnable = oldDepthTestEnable;
|
||||||
_newState.DepthWriteEnable = oldDepthWriteEnable;
|
_newState.DepthWriteEnable = oldDepthWriteEnable;
|
||||||
_newState.Topology = oldTopology;
|
SetPrimitiveTopology(oldTopology);
|
||||||
|
|
||||||
DynamicState.SetViewports(ref oldViewports, oldViewportsCount);
|
DynamicState.SetViewports(ref oldViewports, oldViewportsCount);
|
||||||
|
|
||||||
|
@ -781,7 +781,26 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
shaderSubgroupSize: (int)Capabilities.SubgroupSize,
|
shaderSubgroupSize: (int)Capabilities.SubgroupSize,
|
||||||
storageBufferOffsetAlignment: (int)limits.MinStorageBufferOffsetAlignment,
|
storageBufferOffsetAlignment: (int)limits.MinStorageBufferOffsetAlignment,
|
||||||
textureBufferOffsetAlignment: (int)limits.MinTexelBufferOffsetAlignment,
|
textureBufferOffsetAlignment: (int)limits.MinTexelBufferOffsetAlignment,
|
||||||
gatherBiasPrecision: IsIntelWindows || IsAmdWindows ? (int)Capabilities.SubTexelPrecisionBits : 0);
|
gatherBiasPrecision: IsIntelWindows || IsAmdWindows ? (int)Capabilities.SubTexelPrecisionBits : 0,
|
||||||
|
maximumGpuMemory: GetTotalGPUMemory());
|
||||||
|
}
|
||||||
|
|
||||||
|
private ulong GetTotalGPUMemory()
|
||||||
|
{
|
||||||
|
ulong totalMemory = 0;
|
||||||
|
|
||||||
|
Api.GetPhysicalDeviceMemoryProperties(_physicalDevice.PhysicalDevice, out PhysicalDeviceMemoryProperties memoryProperties);
|
||||||
|
|
||||||
|
for (int i = 0; i < memoryProperties.MemoryHeapCount; i++)
|
||||||
|
{
|
||||||
|
var heap = memoryProperties.MemoryHeaps[i];
|
||||||
|
if ((heap.Flags & MemoryHeapFlags.DeviceLocalBit) == MemoryHeapFlags.DeviceLocalBit)
|
||||||
|
{
|
||||||
|
totalMemory += heap.Size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HardwareInfo GetHardwareInfo()
|
public HardwareInfo GetHardwareInfo()
|
||||||
@ -865,6 +884,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
private void PrintGpuInformation()
|
private void PrintGpuInformation()
|
||||||
{
|
{
|
||||||
Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})");
|
Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})");
|
||||||
|
Logger.Notice.Print(LogClass.Gpu, $"GPU Memory: {GetTotalGPUMemory() / (1024 * 1024)} MiB");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(GraphicsDebugLevel logLevel)
|
public void Initialize(GraphicsDebugLevel logLevel)
|
||||||
|
@ -53,6 +53,7 @@ namespace Ryujinx.SDL2.Common
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_SetHint(SDL_HINT_APP_NAME, "Ryujinx");
|
||||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1");
|
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1");
|
||||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1");
|
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1");
|
||||||
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
|
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user