diff --git a/src/xenia/base/clock_posix.cc b/src/xenia/base/clock_posix.cc index f18082b0e..73a23dc76 100644 --- a/src/xenia/base/clock_posix.cc +++ b/src/xenia/base/clock_posix.cc @@ -2,45 +2,55 @@ ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** - * Copyright 2019 Ben Vanik. All rights reserved. * + * Copyright 2021 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ -#include "xenia/base/clock.h" - #include -#include + +#include "xenia/base/assert.h" +#include "xenia/base/clock.h" namespace xe { uint64_t Clock::host_tick_frequency_platform() { timespec res; - clock_getres(CLOCK_MONOTONIC_RAW, &res); + int error = clock_getres(CLOCK_MONOTONIC_RAW, &res); + assert_zero(error); + assert_zero(res.tv_sec); // Sub second resolution is required. - return uint64_t(res.tv_sec) + uint64_t(res.tv_nsec) * 1000000000ull; + // Convert nano seconds to hertz. Resolution is 1ns on most systems. + return 1000000000ull / res.tv_nsec; } uint64_t Clock::host_tick_count_platform() { - timespec res; - clock_gettime(CLOCK_MONOTONIC_RAW, &res); + timespec tp; + int error = clock_gettime(CLOCK_MONOTONIC_RAW, &tp); + assert_zero(error); - return uint64_t(res.tv_sec) + uint64_t(res.tv_nsec) * 1000000000ull; + return tp.tv_nsec + tp.tv_sec * 1000000000ull; } uint64_t Clock::QueryHostSystemTime() { - struct timeval tv; - gettimeofday(&tv, NULL); + // https://docs.microsoft.com/en-us/windows/win32/sysinfo/converting-a-time-t-value-to-a-file-time + constexpr uint64_t seconds_per_day = 3600 * 24; + // Don't forget the 89 leap days. + constexpr uint64_t seconds_1601_to_1970 = + ((369 * 365 + 89) * seconds_per_day); - uint64_t ret = tv.tv_usec; - ret /= 1000; // usec -> msec + timeval now; + int error = gettimeofday(&now, nullptr); + assert_zero(error); - ret += (tv.tv_sec * 1000); // sec -> msec - return ret; + // NT systems use 100ns intervals. + return static_cast( + (static_cast(now.tv_sec) + seconds_1601_to_1970) * 10000000ull + + now.tv_usec * 10); } uint64_t Clock::QueryHostUptimeMillis() { return host_tick_count_platform() * 1000 / host_tick_frequency_platform(); } -} // namespace xe \ No newline at end of file +} // namespace xe diff --git a/src/xenia/gpu/render_target_cache.cc b/src/xenia/gpu/render_target_cache.cc index ec83cc4fd..76a3a2ef8 100644 --- a/src/xenia/gpu/render_target_cache.cc +++ b/src/xenia/gpu/render_target_cache.cc @@ -845,7 +845,9 @@ RenderTargetCache::GetConfigDepthFloat24Conversion() { uint32_t RenderTargetCache::GetRenderTargetHeight( uint32_t pitch_tiles_at_32bpp, xenos::MsaaSamples msaa_samples) const { - assert_not_zero(pitch_tiles_at_32bpp); + if (!pitch_tiles_at_32bpp) { + return 0; + } // Down to the end of EDRAM. uint32_t tile_rows = (xenos::kEdramTileCount + (pitch_tiles_at_32bpp - 1)) / pitch_tiles_at_32bpp; diff --git a/src/xenia/gpu/render_target_cache.h b/src/xenia/gpu/render_target_cache.h index 383c12f94..a3d580356 100644 --- a/src/xenia/gpu/render_target_cache.h +++ b/src/xenia/gpu/render_target_cache.h @@ -265,11 +265,15 @@ class RenderTargetCache { uint32_t GetPitchTiles() const { return pitch_tiles_at_32bpp << uint32_t(Is64bpp()); } - uint32_t GetWidth() const { + static constexpr uint32_t GetWidth(uint32_t pitch_tiles_at_32bpp, + xenos::MsaaSamples msaa_samples) { return pitch_tiles_at_32bpp * (xenos::kEdramTileWidthSamples >> uint32_t(msaa_samples >= xenos::MsaaSamples::k4X)); } + uint32_t GetWidth() const { + return GetWidth(pitch_tiles_at_32bpp, msaa_samples); + } std::string GetDebugName() const { return fmt::format(