summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-07-01 11:10:27 -0400
committerGravatar FernandoS272019-07-05 15:49:33 -0400
commitf3a39e0c9ce8468859da12e35a52fa088e264d28 (patch)
tree1b8213a87e7cda7ccb5be0828770415d2d78000e /src
parentNVServices: Styling, define constructors as explicit and corrections (diff)
downloadyuzu-f3a39e0c9ce8468859da12e35a52fa088e264d28.tar.gz
yuzu-f3a39e0c9ce8468859da12e35a52fa088e264d28.tar.xz
yuzu-f3a39e0c9ce8468859da12e35a52fa088e264d28.zip
NVServices: Address Feedback
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp14
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.h5
-rw-r--r--src/core/hle/service/nvdrv/interface.cpp2
-rw-r--r--src/core/hle/service/nvdrv/nvdata.h4
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.h23
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.cpp1
-rw-r--r--src/core/hle/service/vi/vi.cpp5
8 files changed, 38 insertions, 21 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
index c918b4225..76494f0b7 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
@@ -36,9 +36,8 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3
36 addr, offset, width, height, stride, static_cast<PixelFormat>(format), 36 addr, offset, width, height, stride, static_cast<PixelFormat>(format),
37 transform, crop_rect}; 37 transform, crop_rect};
38 38
39 auto& instance = system; 39 system.GetPerfStats().EndGameFrame();
40 instance.GetPerfStats().EndGameFrame(); 40 system.GPU().SwapBuffers(framebuffer);
41 instance.GPU().SwapBuffers(framebuffer);
42} 41}
43 42
44} // namespace Service::Nvidia::Devices 43} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index 749aa71d4..1f178d17d 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -87,13 +87,19 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
87 u32 event_id; 87 u32 event_id;
88 if (is_async) { 88 if (is_async) {
89 event_id = params.value & 0x00FF; 89 event_id = params.value & 0x00FF;
90 if (event_id >= 64) { 90 if (event_id >= MaxNvEvents) {
91 std::memcpy(output.data(), &params, sizeof(params)); 91 std::memcpy(output.data(), &params, sizeof(params));
92 return NvResult::BadParameter; 92 return NvResult::BadParameter;
93 } 93 }
94 } else { 94 } else {
95 if (ctrl.fresh_call) { 95 if (ctrl.fresh_call) {
96 event_id = events_interface.GetFreeEvent(); 96 const auto result = events_interface.GetFreeEvent();
97 if (result) {
98 event_id = *result;
99 } else {
100 LOG_CRITICAL(Service_NVDRV, "No Free Events available!");
101 event_id = params.value & 0x00FF;
102 }
97 } else { 103 } else {
98 event_id = ctrl.event_id; 104 event_id = ctrl.event_id;
99 } 105 }
@@ -129,6 +135,7 @@ u32 nvhost_ctrl::IocCtrlEventRegister(const std::vector<u8>& input, std::vector<
129 IocCtrlEventRegisterParams params{}; 135 IocCtrlEventRegisterParams params{};
130 std::memcpy(&params, input.data(), sizeof(params)); 136 std::memcpy(&params, input.data(), sizeof(params));
131 const u32 event_id = params.user_event_id & 0x00FF; 137 const u32 event_id = params.user_event_id & 0x00FF;
138 LOG_DEBUG(Service_NVDRV, " called, user_event_id: {:X}", event_id);
132 if (event_id >= MaxNvEvents) { 139 if (event_id >= MaxNvEvents) {
133 return NvResult::BadParameter; 140 return NvResult::BadParameter;
134 } 141 }
@@ -143,6 +150,7 @@ u32 nvhost_ctrl::IocCtrlEventUnregister(const std::vector<u8>& input, std::vecto
143 IocCtrlEventUnregisterParams params{}; 150 IocCtrlEventUnregisterParams params{};
144 std::memcpy(&params, input.data(), sizeof(params)); 151 std::memcpy(&params, input.data(), sizeof(params));
145 const u32 event_id = params.user_event_id & 0x00FF; 152 const u32 event_id = params.user_event_id & 0x00FF;
153 LOG_DEBUG(Service_NVDRV, " called, user_event_id: {:X}", event_id);
146 if (event_id >= MaxNvEvents) { 154 if (event_id >= MaxNvEvents) {
147 return NvResult::BadParameter; 155 return NvResult::BadParameter;
148 } 156 }
@@ -159,7 +167,7 @@ u32 nvhost_ctrl::IocCtrlEventSignal(const std::vector<u8>& input, std::vector<u8
159 // TODO(Blinkhawk): This is normally called when an NvEvents timeout on WaitSynchronization 167 // TODO(Blinkhawk): This is normally called when an NvEvents timeout on WaitSynchronization
160 // It is believed from RE to cancel the GPU Event. However, better research is required 168 // It is believed from RE to cancel the GPU Event. However, better research is required
161 u32 event_id = params.user_event_id & 0x00FF; 169 u32 event_id = params.user_event_id & 0x00FF;
162 LOG_WARNING(Service_NVDRV, "(STUBBED) called, user_event_id: {:X}", event_id); 170 LOG_DEBUG(Service_NVDRV, " called, user_event_id: {:X}", event_id);
163 if (event_id >= MaxNvEvents) { 171 if (event_id >= MaxNvEvents) {
164 return NvResult::BadParameter; 172 return NvResult::BadParameter;
165 } 173 }
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
index 3ad8e1db1..d2e8fbae9 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
@@ -10,6 +10,7 @@
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "common/swap.h" 11#include "common/swap.h"
12#include "core/hle/service/nvdrv/devices/nvdevice.h" 12#include "core/hle/service/nvdrv/devices/nvdevice.h"
13#include "core/hle/service/nvdrv/nvdata.h"
13 14
14namespace Service::Nvidia::Devices { 15namespace Service::Nvidia::Devices {
15 16
@@ -114,10 +115,6 @@ private:
114 static_assert(sizeof(IoctlGetErrorNotification) == 16, 115 static_assert(sizeof(IoctlGetErrorNotification) == 16,
115 "IoctlGetErrorNotification is incorrect size"); 116 "IoctlGetErrorNotification is incorrect size");
116 117
117 struct Fence {
118 u32_le id;
119 u32_le value;
120 };
121 static_assert(sizeof(Fence) == 8, "Fence is incorrect size"); 118 static_assert(sizeof(Fence) == 8, "Fence is incorrect size");
122 119
123 struct IoctlAllocGpfifoEx { 120 struct IoctlAllocGpfifoEx {
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp
index 6f7c7502a..b8877b6cb 100644
--- a/src/core/hle/service/nvdrv/interface.cpp
+++ b/src/core/hle/service/nvdrv/interface.cpp
@@ -103,7 +103,7 @@ void NVDRV::QueryEvent(Kernel::HLERequestContext& ctx) {
103 103
104 IPC::ResponseBuilder rb{ctx, 3, 1}; 104 IPC::ResponseBuilder rb{ctx, 3, 1};
105 rb.Push(RESULT_SUCCESS); 105 rb.Push(RESULT_SUCCESS);
106 if (event_id < 64) { 106 if (event_id < MaxNvEvents) {
107 rb.PushCopyObjects(nvdrv->GetEvent(event_id)); 107 rb.PushCopyObjects(nvdrv->GetEvent(event_id));
108 rb.Push<u32>(NvResult::Success); 108 rb.Push<u32>(NvResult::Success);
109 } else { 109 } else {
diff --git a/src/core/hle/service/nvdrv/nvdata.h b/src/core/hle/service/nvdrv/nvdata.h
index 22b1dc79b..ac03cbc23 100644
--- a/src/core/hle/service/nvdrv/nvdata.h
+++ b/src/core/hle/service/nvdrv/nvdata.h
@@ -35,9 +35,13 @@ enum class EventState {
35}; 35};
36 36
37struct IoctlCtrl { 37struct IoctlCtrl {
38 // First call done to the servioce for services that call itself again after a call.
38 bool fresh_call{true}; 39 bool fresh_call{true};
40 // Tells the Ioctl Wrapper that it must delay the IPC response and send the thread to sleep
39 bool must_delay{}; 41 bool must_delay{};
42 // Timeout for the delay
40 s64 timeout{}; 43 s64 timeout{};
44 // NV Event Id
41 s32 event_id{-1}; 45 s32 event_id{-1};
42}; 46};
43 47
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h
index 8f7c59a21..a339ab672 100644
--- a/src/core/hle/service/nvdrv/nvdrv.h
+++ b/src/core/hle/service/nvdrv/nvdrv.h
@@ -27,25 +27,34 @@ class nvdevice;
27} 27}
28 28
29struct EventInterface { 29struct EventInterface {
30 // Mask representing currently busy events
30 u64 events_mask{}; 31 u64 events_mask{};
32 // Each kernel event associated to an NV event
31 std::array<Kernel::EventPair, MaxNvEvents> events; 33 std::array<Kernel::EventPair, MaxNvEvents> events;
34 // The status of the current NVEvent
32 std::array<EventState, MaxNvEvents> status{}; 35 std::array<EventState, MaxNvEvents> status{};
36 // Tells if an NVEvent is registered or not
33 std::array<bool, MaxNvEvents> registered{}; 37 std::array<bool, MaxNvEvents> registered{};
38 // When an NVEvent is waiting on GPU interrupt, this is the sync_point
39 // associated with it.
34 std::array<u32, MaxNvEvents> assigned_syncpt{}; 40 std::array<u32, MaxNvEvents> assigned_syncpt{};
41 // This is the value of the GPU interrupt for which the NVEvent is waiting
42 // for.
35 std::array<u32, MaxNvEvents> assigned_value{}; 43 std::array<u32, MaxNvEvents> assigned_value{};
36 static constexpr u32 null_event = 0xFFFFFFFF; 44 // Constant to denote an unasigned syncpoint.
37 u32 GetFreeEvent() const { 45 static constexpr u32 unassigned_syncpt = 0xFFFFFFFF;
46 std::optional<u32> GetFreeEvent() const {
38 u64 mask = events_mask; 47 u64 mask = events_mask;
39 for (u32 i = 0; i < MaxNvEvents; i++) { 48 for (u32 i = 0; i < MaxNvEvents; i++) {
40 const bool is_free = (mask & 0x1) == 0; 49 const bool is_free = (mask & 0x1) == 0;
41 if (is_free) { 50 if (is_free) {
42 if (status[i] == EventState::Registered || status[i] == EventState::Free) { 51 if (status[i] == EventState::Registered || status[i] == EventState::Free) {
43 return i; 52 return {i};
44 } 53 }
45 } 54 }
46 mask = mask >> 1; 55 mask = mask >> 1;
47 } 56 }
48 return null_event; 57 return {};
49 } 58 }
50 void SetEventStatus(const u32 event_id, EventState new_status) { 59 void SetEventStatus(const u32 event_id, EventState new_status) {
51 EventState old_status = status[event_id]; 60 EventState old_status = status[event_id];
@@ -57,7 +66,7 @@ struct EventInterface {
57 registered[event_id] = true; 66 registered[event_id] = true;
58 } 67 }
59 if (new_status == EventState::Waiting || new_status == EventState::Busy) { 68 if (new_status == EventState::Waiting || new_status == EventState::Busy) {
60 events_mask |= (1 << event_id); 69 events_mask |= (1ULL << event_id);
61 } 70 }
62 } 71 }
63 void RegisterEvent(const u32 event_id) { 72 void RegisterEvent(const u32 event_id) {
@@ -74,8 +83,8 @@ struct EventInterface {
74 } 83 }
75 void LiberateEvent(const u32 event_id) { 84 void LiberateEvent(const u32 event_id) {
76 status[event_id] = registered[event_id] ? EventState::Registered : EventState::Free; 85 status[event_id] = registered[event_id] ? EventState::Registered : EventState::Free;
77 events_mask &= ~(1 << event_id); 86 events_mask &= ~(1ULL << event_id);
78 assigned_syncpt[event_id] = 0xFFFFFFFF; 87 assigned_syncpt[event_id] = unassigned_syncpt;
79 assigned_value[event_id] = 0; 88 assigned_value[event_id] = 0;
80 } 89 }
81}; 90};
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp
index ddc224f2c..e1a07d3ee 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue.cpp
@@ -80,6 +80,7 @@ void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform,
80 80
81std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() { 81std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() {
82 auto itr = queue.end(); 82 auto itr = queue.end();
83 // Iterate to find a queued buffer matching the requested slot.
83 while (itr == queue.end() && !queue_sequence.empty()) { 84 while (itr == queue.end() && !queue_sequence.empty()) {
84 u32 slot = queue_sequence.front(); 85 u32 slot = queue_sequence.front();
85 itr = std::find_if(queue.begin(), queue.end(), [&slot](const Buffer& buffer) { 86 itr = std::find_if(queue.begin(), queue.end(), [&slot](const Buffer& buffer) {
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 894bcdc04..199b30635 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -536,7 +536,7 @@ private:
536 536
537 if (result) { 537 if (result) {
538 // Buffer is available 538 // Buffer is available
539 IGBPDequeueBufferResponseParcel response{(*result).first, *(*result).second}; 539 IGBPDequeueBufferResponseParcel response{result->first, *result->second};
540 ctx.WriteBuffer(response.Serialize()); 540 ctx.WriteBuffer(response.Serialize());
541 } else { 541 } else {
542 // Wait the current thread until a buffer becomes available 542 // Wait the current thread until a buffer becomes available
@@ -549,8 +549,7 @@ private:
549 auto result = buffer_queue.DequeueBuffer(width, height); 549 auto result = buffer_queue.DequeueBuffer(width, height);
550 ASSERT_MSG(result != std::nullopt, "Could not dequeue buffer."); 550 ASSERT_MSG(result != std::nullopt, "Could not dequeue buffer.");
551 551
552 IGBPDequeueBufferResponseParcel response{(*result).first, 552 IGBPDequeueBufferResponseParcel response{result->first, *result->second};
553 *(*result).second};
554 ctx.WriteBuffer(response.Serialize()); 553 ctx.WriteBuffer(response.Serialize());
555 IPC::ResponseBuilder rb{ctx, 2}; 554 IPC::ResponseBuilder rb{ctx, 2};
556 rb.Push(RESULT_SUCCESS); 555 rb.Push(RESULT_SUCCESS);