summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorFernando Sahmkow <fsahmkow27@gmail.com>2022-01-30 10:31:13 +0100
committerFernando Sahmkow <fsahmkow27@gmail.com>2022-10-06 21:00:52 +0200
commit668e80a9f42fb4ce0e16f6381d05bcbd286b2da1 (patch)
treea1c668d6c3d00eade849b1d31dba4116095e4c12 /src/core
parentTexture Cache: Fix GC and GPU Modified on Joins. (diff)
downloadyuzu-668e80a9f42fb4ce0e16f6381d05bcbd286b2da1.tar
yuzu-668e80a9f42fb4ce0e16f6381d05bcbd286b2da1.tar.gz
yuzu-668e80a9f42fb4ce0e16f6381d05bcbd286b2da1.tar.bz2
yuzu-668e80a9f42fb4ce0e16f6381d05bcbd286b2da1.tar.lz
yuzu-668e80a9f42fb4ce0e16f6381d05bcbd286b2da1.tar.xz
yuzu-668e80a9f42fb4ce0e16f6381d05bcbd286b2da1.tar.zst
yuzu-668e80a9f42fb4ce0e16f6381d05bcbd286b2da1.zip
Diffstat (limited to '')
-rw-r--r--src/core/core.cpp12
-rw-r--r--src/core/core.h9
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp19
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.h4
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp10
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp9
7 files changed, 53 insertions, 12 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 121092868..fa059a394 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -51,6 +51,7 @@
#include "core/telemetry_session.h"
#include "core/tools/freezer.h"
#include "network/network.h"
+#include "video_core/host1x/host1x.h"
#include "video_core/renderer_base.h"
#include "video_core/video_core.h"
@@ -215,6 +216,7 @@ struct System::Impl {
telemetry_session = std::make_unique<Core::TelemetrySession>();
+ host1x_core = std::make_unique<Tegra::Host1x::Host1x>();
gpu_core = VideoCore::CreateGPU(emu_window, system);
if (!gpu_core) {
return SystemResultStatus::ErrorVideoCore;
@@ -373,6 +375,7 @@ struct System::Impl {
app_loader.reset();
audio_core.reset();
gpu_core.reset();
+ host1x_core.reset();
perf_stats.reset();
kernel.Shutdown();
memory.Reset();
@@ -450,6 +453,7 @@ struct System::Impl {
/// AppLoader used to load the current executing application
std::unique_ptr<Loader::AppLoader> app_loader;
std::unique_ptr<Tegra::GPU> gpu_core;
+ std::unique_ptr<Tegra::Host1x::Host1x> host1x_core;
std::unique_ptr<Hardware::InterruptManager> interrupt_manager;
std::unique_ptr<Core::DeviceMemory> device_memory;
std::unique_ptr<AudioCore::AudioCore> audio_core;
@@ -668,6 +672,14 @@ const Tegra::GPU& System::GPU() const {
return *impl->gpu_core;
}
+Tegra::Host1x::Host1x& System::Host1x() {
+ return *impl->host1x_core;
+}
+
+const Tegra::Host1x::Host1x& System::Host1x() const {
+ return *impl->host1x_core;
+}
+
Core::Hardware::InterruptManager& System::InterruptManager() {
return *impl->interrupt_manager;
}
diff --git a/src/core/core.h b/src/core/core.h
index 0ce3b1d60..e4168a921 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -74,6 +74,9 @@ class TimeManager;
namespace Tegra {
class DebugContext;
class GPU;
+namespace Host1x {
+class Host1x;
+} // namespace Host1x
} // namespace Tegra
namespace VideoCore {
@@ -260,6 +263,12 @@ public:
/// Gets an immutable reference to the GPU interface.
[[nodiscard]] const Tegra::GPU& GPU() const;
+ /// Gets a mutable reference to the Host1x interface
+ [[nodiscard]] Tegra::Host1x::Host1x& Host1x();
+
+ /// Gets an immutable reference to the Host1x interface.
+ [[nodiscard]] const Tegra::Host1x::Host1x& Host1x() const;
+
/// Gets a mutable reference to the renderer.
[[nodiscard]] VideoCore::RendererBase& Renderer();
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
index b1c0e9eb2..e6a976714 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
@@ -50,7 +50,7 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, android::PixelFormat form
stride, format, transform, crop_rect};
system.GetPerfStats().EndSystemFrame();
- system.GPU().SwapBuffers(&framebuffer);
+ system.GPU().RequestSwapBuffers(&framebuffer, nullptr, 0);
system.SpeedLimiter().DoSpeedLimiting(system.CoreTiming().GetGlobalTimeUs());
system.GetPerfStats().BeginSystemFrame();
}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index 54074af75..ffe42d423 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -18,6 +18,7 @@
#include "core/hle/service/nvdrv/core/syncpoint_manager.h"
#include "core/hle/service/nvdrv/devices/nvhost_ctrl.h"
#include "video_core/gpu.h"
+#include "video_core/host1x/host1x.h"
namespace Service::Nvidia::Devices {
@@ -129,7 +130,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
return NvResult::Success;
}
- auto& gpu = system.GPU();
+ auto& host1x_syncpoint_manager = system.Host1x().GetSyncpointManager();
const u32 target_value = params.fence.value;
auto lock = NvEventsLock();
@@ -149,7 +150,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
if (events[slot].fails > 2) {
{
auto lk = system.StallProcesses();
- gpu.WaitFence(fence_id, target_value);
+ host1x_syncpoint_manager.WaitHost(fence_id, target_value);
system.UnstallProcesses();
}
params.value.raw = target_value;
@@ -198,7 +199,15 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
}
params.value.raw |= slot;
- gpu.RegisterSyncptInterrupt(fence_id, target_value);
+ event.wait_handle =
+ host1x_syncpoint_manager.RegisterHostAction(fence_id, target_value, [this, slot]() {
+ auto& event = events[slot];
+ if (event.status.exchange(EventState::Signalling, std::memory_order_acq_rel) ==
+ EventState::Waiting) {
+ event.kevent->GetWritableEvent().Signal();
+ }
+ event.status.store(EventState::Signalled, std::memory_order_release);
+ });
return NvResult::Timeout;
}
@@ -288,8 +297,10 @@ NvResult nvhost_ctrl::IocCtrlClearEventWait(const std::vector<u8>& input, std::v
auto& event = events[event_id];
if (event.status.exchange(EventState::Cancelling, std::memory_order_acq_rel) ==
EventState::Waiting) {
- system.GPU().CancelSyncptInterrupt(event.assigned_syncpt, event.assigned_value);
+ auto& host1x_syncpoint_manager = system.Host1x().GetSyncpointManager();
+ host1x_syncpoint_manager.DeregisterHostAction(event.assigned_syncpt, event.wait_handle);
syncpoint_manager.RefreshSyncpoint(event.assigned_syncpt);
+ event.wait_handle = {};
}
event.fails++;
event.status.store(EventState::Cancelled, std::memory_order_release);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
index d56aea405..136a1e925 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
@@ -11,6 +11,7 @@
#include "common/common_types.h"
#include "core/hle/service/nvdrv/devices/nvdevice.h"
#include "core/hle/service/nvdrv/nvdrv.h"
+#include "video_core/host1x/syncpoint_manager.h"
namespace Service::Nvidia::NvCore {
class Container;
@@ -78,6 +79,9 @@ private:
// Tells if an NVEvent is registered or not
bool registered{};
+ // Used for waiting on a syncpoint & canceling it.
+ Tegra::Host1x::SyncpointManager::ActionHandle wait_handle{};
+
bool IsBeingUsed() {
const auto current_status = status.load(std::memory_order_acquire);
return current_status == EventState::Waiting ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index 38d45cb79..db3e266ad 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -210,10 +210,10 @@ NvResult nvhost_gpu::AllocateObjectContext(const std::vector<u8>& input, std::ve
static std::vector<Tegra::CommandHeader> BuildWaitCommandList(NvFence fence) {
return {
- Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceValue, 1,
+ Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointPayload, 1,
Tegra::SubmissionMode::Increasing),
{fence.value},
- Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceAction, 1,
+ Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointOperation, 1,
Tegra::SubmissionMode::Increasing),
BuildFenceAction(Tegra::Engines::Puller::FenceOperation::Acquire, fence.id),
};
@@ -222,12 +222,12 @@ static std::vector<Tegra::CommandHeader> BuildWaitCommandList(NvFence fence) {
static std::vector<Tegra::CommandHeader> BuildIncrementCommandList(NvFence fence,
u32 add_increment) {
std::vector<Tegra::CommandHeader> result{
- Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceValue, 1,
+ Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointPayload, 1,
Tegra::SubmissionMode::Increasing),
{}};
for (u32 count = 0; count < add_increment; ++count) {
- result.emplace_back(Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceAction, 1,
+ result.emplace_back(Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointOperation, 1,
Tegra::SubmissionMode::Increasing));
result.emplace_back(
BuildFenceAction(Tegra::Engines::Puller::FenceOperation::Increment, fence.id));
@@ -239,7 +239,7 @@ static std::vector<Tegra::CommandHeader> BuildIncrementCommandList(NvFence fence
static std::vector<Tegra::CommandHeader> BuildIncrementWithWfiCommandList(NvFence fence,
u32 add_increment) {
std::vector<Tegra::CommandHeader> result{
- Tegra::BuildCommandHeader(Tegra::BufferMethods::WaitForInterrupt, 1,
+ Tegra::BuildCommandHeader(Tegra::BufferMethods::WaitForIdle, 1,
Tegra::SubmissionMode::Increasing),
{}};
const std::vector<Tegra::CommandHeader> increment{
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index 8c3013f83..aa112021d 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -24,6 +24,8 @@
#include "core/hle/service/vi/layer/vi_layer.h"
#include "core/hle/service/vi/vi_results.h"
#include "video_core/gpu.h"
+#include "video_core/host1x/host1x.h"
+#include "video_core/host1x/syncpoint_manager.h"
namespace Service::NVFlinger {
@@ -267,12 +269,12 @@ void NVFlinger::Compose() {
return; // We are likely shutting down
}
- auto& gpu = system.GPU();
+ auto& syncpoint_manager = system.Host1x().GetSyncpointManager();
const auto& multi_fence = buffer.fence;
guard->unlock();
for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) {
const auto& fence = multi_fence.fences[fence_id];
- gpu.WaitFence(fence.id, fence.value);
+ syncpoint_manager.WaitGuest(fence.id, fence.value);
}
guard->lock();
@@ -284,6 +286,7 @@ void NVFlinger::Compose() {
auto nvdisp = nvdrv->GetDevice<Nvidia::Devices::nvdisp_disp0>(disp_fd);
ASSERT(nvdisp);
+ guard->unlock();
Common::Rectangle<int> crop_rect{
static_cast<int>(buffer.crop.Left()), static_cast<int>(buffer.crop.Top()),
static_cast<int>(buffer.crop.Right()), static_cast<int>(buffer.crop.Bottom())};
@@ -292,6 +295,8 @@ void NVFlinger::Compose() {
igbp_buffer.Width(), igbp_buffer.Height(), igbp_buffer.Stride(),
static_cast<android::BufferTransformFlags>(buffer.transform), crop_rect);
+ guard->lock();
+
swap_interval = buffer.swap_interval;
auto fence = android::Fence::NoFence();