Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
c52158b733 | |||
fd6d3ec88f | |||
0a0a95fd81 |
@ -115,7 +115,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
||||
}
|
||||
else /* if (type == LaunchDmaSemaphoreType.ReleaseFourWordSemaphore) */
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Gpu, "DMA semaphore type ReleaseFourWordSemaphore was used, but is not currently implemented.");
|
||||
_channel.MemoryManager.Write(address + 8, _context.GetTimestamp());
|
||||
_channel.MemoryManager.Write(address, (ulong)_state.State.SetSemaphorePayload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +75,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
|
||||
|
||||
SemaphoredOperation operation = _state.State.SemaphoredOperation;
|
||||
|
||||
if (_state.State.SemaphoredReleaseSize == SemaphoredReleaseSize.SixteenBytes)
|
||||
{
|
||||
_parent.MemoryManager.Write(address + 4, 0);
|
||||
_parent.MemoryManager.Write(address + 8, _context.GetTimestamp());
|
||||
}
|
||||
|
||||
// TODO: Acquire operations (Wait), interrupts for invalid combinations.
|
||||
if (operation == SemaphoredOperation.Release)
|
||||
{
|
||||
|
@ -1,6 +1,4 @@
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using System.Runtime.InteropServices;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
{
|
||||
@ -9,9 +7,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
class SemaphoreUpdater
|
||||
{
|
||||
private const int NsToTicksFractionNumerator = 384;
|
||||
private const int NsToTicksFractionDenominator = 625;
|
||||
|
||||
/// <summary>
|
||||
/// GPU semaphore operation.
|
||||
/// </summary>
|
||||
@ -154,14 +149,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
{
|
||||
ulong gpuVa = _state.State.SemaphoreAddress.Pack();
|
||||
|
||||
ulong ticks = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds);
|
||||
|
||||
if (GraphicsConfig.FastGpuTime)
|
||||
{
|
||||
// Divide by some amount to report time as if operations were performed faster than they really are.
|
||||
// This can prevent some games from switching to a lower resolution because rendering is too slow.
|
||||
ticks /= 256;
|
||||
}
|
||||
ulong ticks = _context.GetTimestamp();
|
||||
|
||||
ICounterEvent counter = null;
|
||||
|
||||
@ -197,27 +185,5 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
|
||||
_channel.MemoryManager.CounterCache.AddOrUpdate(gpuVa, counter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a nanoseconds timestamp value to Maxwell time ticks.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The frequency is 614400000 Hz.
|
||||
/// </remarks>
|
||||
/// <param name="nanoseconds">Timestamp in nanoseconds</param>
|
||||
/// <returns>Maxwell ticks</returns>
|
||||
private static ulong ConvertNanosecondsToTicks(ulong nanoseconds)
|
||||
{
|
||||
// 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 / NsToTicksFractionDenominator;
|
||||
|
||||
ulong rounded = divided * NsToTicksFractionDenominator;
|
||||
|
||||
ulong errorBias = (nanoseconds - rounded) * NsToTicksFractionNumerator / NsToTicksFractionDenominator;
|
||||
|
||||
return divided * NsToTicksFractionNumerator + errorBias;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Gpu.Engine.GPFifo;
|
||||
using Ryujinx.Graphics.Gpu.Memory;
|
||||
@ -15,6 +16,9 @@ namespace Ryujinx.Graphics.Gpu
|
||||
/// </summary>
|
||||
public sealed class GpuContext : IDisposable
|
||||
{
|
||||
private const int NsToTicksFractionNumerator = 384;
|
||||
private const int NsToTicksFractionDenominator = 625;
|
||||
|
||||
/// <summary>
|
||||
/// Event signaled when the host emulation context is ready to be used by the gpu context.
|
||||
/// </summary>
|
||||
@ -180,6 +184,46 @@ namespace Ryujinx.Graphics.Gpu
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a nanoseconds timestamp value to Maxwell time ticks.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The frequency is 614400000 Hz.
|
||||
/// </remarks>
|
||||
/// <param name="nanoseconds">Timestamp in nanoseconds</param>
|
||||
/// <returns>Maxwell ticks</returns>
|
||||
private static ulong ConvertNanosecondsToTicks(ulong nanoseconds)
|
||||
{
|
||||
// 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 / NsToTicksFractionDenominator;
|
||||
|
||||
ulong rounded = divided * NsToTicksFractionDenominator;
|
||||
|
||||
ulong errorBias = (nanoseconds - rounded) * NsToTicksFractionNumerator / NsToTicksFractionDenominator;
|
||||
|
||||
return divided * NsToTicksFractionNumerator + errorBias;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the GPU timer.
|
||||
/// </summary>
|
||||
/// <returns>The current GPU timestamp</returns>
|
||||
public ulong GetTimestamp()
|
||||
{
|
||||
ulong ticks = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds);
|
||||
|
||||
if (GraphicsConfig.FastGpuTime)
|
||||
{
|
||||
// Divide by some amount to report time as if operations were performed faster than they really are.
|
||||
// This can prevent some games from switching to a lower resolution because rendering is too slow.
|
||||
ticks /= 256;
|
||||
}
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shader cache state update handler.
|
||||
/// </summary>
|
||||
|
@ -49,6 +49,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
private readonly float[] _scales;
|
||||
private bool _scaleChanged;
|
||||
private int _lastFragmentTotal;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance of the texture bindings manager.
|
||||
@ -288,26 +289,30 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// </summary>
|
||||
private void CommitRenderScale()
|
||||
{
|
||||
// Stage 0 total: Compute or Vertex.
|
||||
int total = _textureBindingsCount[0] + _imageBindingsCount[0];
|
||||
|
||||
int fragmentIndex = (int)ShaderStage.Fragment - 1;
|
||||
int fragmentTotal = _isCompute ? 0 : (_textureBindingsCount[fragmentIndex] + _imageBindingsCount[fragmentIndex]);
|
||||
|
||||
if (total != 0 && fragmentTotal != _lastFragmentTotal)
|
||||
{
|
||||
// Must update scales in the support buffer if:
|
||||
// - Vertex stage has bindings.
|
||||
// - Fragment stage binding count has been updated since last render scale update.
|
||||
|
||||
_scaleChanged = true;
|
||||
}
|
||||
|
||||
if (_scaleChanged)
|
||||
{
|
||||
int fragmentTotal = 0;
|
||||
int total;
|
||||
|
||||
if (!_isCompute)
|
||||
{
|
||||
int fragmentIndex = (int)ShaderStage.Fragment - 1;
|
||||
fragmentTotal = _textureBindingsCount[fragmentIndex] + _imageBindingsCount[fragmentIndex];
|
||||
|
||||
int vertexIndex = (int)ShaderStage.Vertex - 1;
|
||||
int vertexTotal = _textureBindingsCount[vertexIndex] + _imageBindingsCount[vertexIndex];
|
||||
|
||||
total = fragmentTotal + vertexTotal;
|
||||
}
|
||||
else
|
||||
{
|
||||
total = _textureBindingsCount[0] + _imageBindingsCount[0];
|
||||
total += fragmentTotal; // Add the fragment bindings to the total.
|
||||
}
|
||||
|
||||
_lastFragmentTotal = fragmentTotal;
|
||||
|
||||
_context.Renderer.Pipeline.UpdateRenderScale(_scales, total, fragmentTotal);
|
||||
|
||||
_scaleChanged = false;
|
||||
|
@ -396,7 +396,7 @@ namespace Ryujinx.Modules
|
||||
|
||||
if (!OperatingSystem.IsWindows())
|
||||
{
|
||||
chmod(ryuBin, 0777);
|
||||
chmod(ryuBin, 493);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user