/// <summary> /// Writes a GPU counter to guest memory. /// This also writes the current timestamp value. /// </summary> /// <param name="state">Current GPU state</param> /// <param name="type">Counter to be written to memory</param> private void ReportCounter(GpuState state, ReportCounterType type) { CounterData counterData = new CounterData(); var rs = state.Get <SemaphoreState>(MethodOffset.ReportState); ulong gpuVa = rs.Address.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; } ICounterEvent counter = null; EventHandler <ulong> resultHandler = (object evt, ulong result) => { counterData.Counter = result; counterData.Timestamp = ticks; Span <CounterData> counterDataSpan = MemoryMarshal.CreateSpan(ref counterData, 1); Span <byte> data = MemoryMarshal.Cast <CounterData, byte>(counterDataSpan); if (counter?.Invalid != true) { _context.MemoryAccessor.Write(gpuVa, data); } }; switch (type) { case ReportCounterType.Zero: resultHandler(null, 0); break; case ReportCounterType.SamplesPassed: counter = _context.Renderer.ReportCounter(CounterType.SamplesPassed, resultHandler); break; case ReportCounterType.PrimitivesGenerated: counter = _context.Renderer.ReportCounter(CounterType.PrimitivesGenerated, resultHandler); break; case ReportCounterType.TransformFeedbackPrimitivesWritten: counter = _context.Renderer.ReportCounter(CounterType.TransformFeedbackPrimitivesWritten, resultHandler); break; } _counterCache.AddOrUpdate(gpuVa, counter); }
/// <summary> /// Writes a GPU counter to guest memory. /// </summary> /// <param name="state">Current GPU state</param> /// <param name="argument">Method call argument</param> private void Report(GpuState state, int argument) { SemaphoreOperation op = (SemaphoreOperation)(argument & 3); ReportCounterType type = (ReportCounterType)((argument >> 23) & 0x1f); switch (op) { case SemaphoreOperation.Release: ReleaseSemaphore(state); break; case SemaphoreOperation.Counter: ReportCounter(state, type); break; } }
/// <summary> /// Writes a GPU counter to guest memory. /// </summary> /// <param name="argument">Method call argument</param> public void Report(int argument) { SemaphoreOperation op = (SemaphoreOperation)(argument & 3); ReportCounterType type = (ReportCounterType)((argument >> 23) & 0x1f); switch (op) { case SemaphoreOperation.Release: ReleaseSemaphore(); break; case SemaphoreOperation.Counter: ReportCounter(type); break; } }
/// <summary> /// Writes a GPU counter to guest memory. /// </summary> /// <param name="state">Current GPU state</param> /// <param name="argument">Method call argument</param> private void Report(GpuState state, int argument) { ReportMode mode = (ReportMode)(argument & 3); ReportCounterType type = (ReportCounterType)((argument >> 23) & 0x1f); switch (mode) { case ReportMode.Release: ReleaseSemaphore(state); break; // case ReportMode.Counter: ReportCounter(state, type); break; } }
/// <summary> /// Writes a GPU counter to guest memory. /// This also writes the current timestamp value. /// </summary> /// <param name="type">Counter to be written to memory</param> private void ReportCounter(ReportCounterType type) { 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; } ICounterEvent counter = null; void resultHandler(object evt, ulong result) { CounterData counterData = new CounterData { Counter = result, Timestamp = ticks }; if (counter?.Invalid != true) { _channel.MemoryManager.Write(gpuVa, counterData); } } switch (type) { case ReportCounterType.Zero: resultHandler(null, 0); break; case ReportCounterType.SamplesPassed: counter = _context.Renderer.ReportCounter(CounterType.SamplesPassed, resultHandler); break; case ReportCounterType.PrimitivesGenerated: counter = _context.Renderer.ReportCounter(CounterType.PrimitivesGenerated, resultHandler); break; case ReportCounterType.TransformFeedbackPrimitivesWritten: counter = _context.Renderer.ReportCounter(CounterType.TransformFeedbackPrimitivesWritten, resultHandler); break; } _channel.MemoryManager.CounterCache.AddOrUpdate(gpuVa, counter); }
/// <summary> /// Writes a GPU counter to guest memory. /// This also writes the current timestamp value. /// </summary> /// <param name="state">Current GPU state</param> /// <param name="type">Counter to be written to memory</param> private void ReportCounter(GpuState state, ReportCounterType type) { CounterData counterData = new CounterData(); ulong counter = 0; switch (type) { case ReportCounterType.Zero: counter = 0; break; case ReportCounterType.SamplesPassed: counter = _context.Renderer.GetCounter(CounterType.SamplesPassed); break; case ReportCounterType.PrimitivesGenerated: counter = _context.Renderer.GetCounter(CounterType.PrimitivesGenerated); break; case ReportCounterType.TransformFeedbackPrimitivesWritten: counter = _context.Renderer.GetCounter(CounterType.TransformFeedbackPrimitivesWritten); break; } 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; } counterData.Counter = counter; counterData.Timestamp = ticks; Span <CounterData> counterDataSpan = MemoryMarshal.CreateSpan(ref counterData, 1); Span <byte> data = MemoryMarshal.Cast <CounterData, byte>(counterDataSpan); var rs = state.Get <ReportState>(MethodOffset.ReportState); _context.MemoryAccessor.Write(rs.Address.Pack(), data); _counterCache.AddOrUpdate(rs.Address.Pack()); }
/// <summary> /// Writes a GPU counter to guest memory. /// This also writes the current timestamp value. /// </summary> /// <param name="state">Current GPU state</param> /// <param name="type">Counter to be written to memory</param> private void ReportCounter(GpuState state, ReportCounterType type) { CounterData counterData = new CounterData(); ulong counter = 0; switch (type) { case ReportCounterType.Zero: counter = 0; break; case ReportCounterType.SamplesPassed: counter = _context.Renderer.GetCounter(CounterType.SamplesPassed); break; case ReportCounterType.PrimitivesGenerated: counter = _context.Renderer.GetCounter(CounterType.PrimitivesGenerated); break; case ReportCounterType.TransformFeedbackPrimitivesWritten: counter = _context.Renderer.GetCounter(CounterType.TransformFeedbackPrimitivesWritten); break; } ulong ticks; if (GraphicsConfig.FastGpuTime) { ticks = _runningCounter++; } else { ticks = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds); } counterData.Counter = counter; counterData.Timestamp = ticks; Span <CounterData> counterDataSpan = MemoryMarshal.CreateSpan(ref counterData, 1); Span <byte> data = MemoryMarshal.Cast <CounterData, byte>(counterDataSpan); var rs = state.Get <ReportState>(MethodOffset.ReportState); _context.MemoryAccessor.Write(rs.Address.Pack(), data); }
/// <summary> /// Writes a GPU counter to guest memory. /// This also writes the current timestamp value. /// </summary> /// <param name="type">Counter to be written to memory</param> private void ReportCounter(ReportCounterType type) { ulong gpuVa = _state.State.SemaphoreAddress.Pack(); ulong ticks = _context.GetTimestamp(); ICounterEvent counter = null; void resultHandler(object evt, ulong result) { CounterData counterData = new CounterData { Counter = result, Timestamp = ticks }; if (counter?.Invalid != true) { _channel.MemoryManager.Write(gpuVa, counterData); } } switch (type) { case ReportCounterType.Zero: resultHandler(null, 0); break; case ReportCounterType.SamplesPassed: counter = _context.Renderer.ReportCounter(CounterType.SamplesPassed, resultHandler, false); break; case ReportCounterType.PrimitivesGenerated: counter = _context.Renderer.ReportCounter(CounterType.PrimitivesGenerated, resultHandler, false); break; case ReportCounterType.TransformFeedbackPrimitivesWritten: counter = _context.Renderer.ReportCounter(CounterType.TransformFeedbackPrimitivesWritten, resultHandler, false); break; } _channel.MemoryManager.CounterCache.AddOrUpdate(gpuVa, counter); }