summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/am/am.cpp77
-rw-r--r--src/core/hle/service/am/am.h29
-rw-r--r--src/core/hle/service/am/applet_ae.cpp34
-rw-r--r--src/core/hle/service/am/applet_ae.h6
-rw-r--r--src/core/hle/service/am/applet_oe.cpp21
-rw-r--r--src/core/hle/service/am/applet_oe.h6
-rw-r--r--src/video_core/CMakeLists.txt1
-rw-r--r--src/video_core/engines/maxwell_3d.cpp8
-rw-r--r--src/video_core/engines/maxwell_3d.h6
-rw-r--r--src/video_core/rasterizer_cache.cpp7
-rw-r--r--src/video_core/rasterizer_cache.h9
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp4
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.h4
-rw-r--r--src/video_core/renderer_opengl/gl_primitive_assembler.cpp1
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp30
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h3
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp4
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h4
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp4
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.h4
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp18
-rw-r--r--src/yuzu/configuration/configure_general.cpp32
-rw-r--r--src/yuzu/configuration/configure_general.h1
23 files changed, 253 insertions, 60 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index ac3ff9f20..0477ce66e 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -338,7 +338,54 @@ void ISelfController::GetIdleTimeDetectionExtension(Kernel::HLERequestContext& c
338 LOG_WARNING(Service_AM, "(STUBBED) called"); 338 LOG_WARNING(Service_AM, "(STUBBED) called");
339} 339}
340 340
341ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter") { 341AppletMessageQueue::AppletMessageQueue() {
342 auto& kernel = Core::System::GetInstance().Kernel();
343 on_new_message = Kernel::Event::Create(kernel, Kernel::ResetType::Sticky,
344 "AMMessageQueue:OnMessageRecieved");
345 on_operation_mode_changed = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
346 "AMMessageQueue:OperationModeChanged");
347}
348
349AppletMessageQueue::~AppletMessageQueue() = default;
350
351const Kernel::SharedPtr<Kernel::Event>& AppletMessageQueue::GetMesssageRecieveEvent() const {
352 return on_new_message;
353}
354
355const Kernel::SharedPtr<Kernel::Event>& AppletMessageQueue::GetOperationModeChangedEvent() const {
356 return on_operation_mode_changed;
357}
358
359void AppletMessageQueue::PushMessage(AppletMessage msg) {
360 messages.push(msg);
361 on_new_message->Signal();
362}
363
364AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() {
365 if (messages.empty()) {
366 on_new_message->Clear();
367 return AppletMessage::NoMessage;
368 }
369 auto msg = messages.front();
370 messages.pop();
371 if (messages.empty()) {
372 on_new_message->Clear();
373 }
374 return msg;
375}
376
377std::size_t AppletMessageQueue::GetMessageCount() const {
378 return messages.size();
379}
380
381void AppletMessageQueue::OperationModeChanged() {
382 PushMessage(AppletMessage::OperationModeChanged);
383 PushMessage(AppletMessage::PerformanceModeChanged);
384 on_operation_mode_changed->Signal();
385}
386
387ICommonStateGetter::ICommonStateGetter(std::shared_ptr<AppletMessageQueue> msg_queue)
388 : ServiceFramework("ICommonStateGetter"), msg_queue(std::move(msg_queue)) {
342 // clang-format off 389 // clang-format off
343 static const FunctionInfo functions[] = { 390 static const FunctionInfo functions[] = {
344 {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"}, 391 {0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
@@ -388,21 +435,19 @@ void ICommonStateGetter::GetBootMode(Kernel::HLERequestContext& ctx) {
388} 435}
389 436
390void ICommonStateGetter::GetEventHandle(Kernel::HLERequestContext& ctx) { 437void ICommonStateGetter::GetEventHandle(Kernel::HLERequestContext& ctx) {
391 event->Signal();
392
393 IPC::ResponseBuilder rb{ctx, 2, 1}; 438 IPC::ResponseBuilder rb{ctx, 2, 1};
394 rb.Push(RESULT_SUCCESS); 439 rb.Push(RESULT_SUCCESS);
395 rb.PushCopyObjects(event); 440 rb.PushCopyObjects(msg_queue->GetMesssageRecieveEvent());
396 441
397 LOG_WARNING(Service_AM, "(STUBBED) called"); 442 LOG_DEBUG(Service_AM, "called");
398} 443}
399 444
400void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) { 445void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) {
401 IPC::ResponseBuilder rb{ctx, 3}; 446 IPC::ResponseBuilder rb{ctx, 3};
402 rb.Push(RESULT_SUCCESS); 447 rb.Push(RESULT_SUCCESS);
403 rb.Push<u32>(15); 448 rb.PushEnum<AppletMessageQueue::AppletMessage>(msg_queue->PopMessage());
404 449
405 LOG_WARNING(Service_AM, "(STUBBED) called"); 450 LOG_DEBUG(Service_AM, "called");
406} 451}
407 452
408void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) { 453void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
@@ -414,13 +459,11 @@ void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
414} 459}
415 460
416void ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(Kernel::HLERequestContext& ctx) { 461void ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(Kernel::HLERequestContext& ctx) {
417 event->Signal();
418
419 IPC::ResponseBuilder rb{ctx, 2, 1}; 462 IPC::ResponseBuilder rb{ctx, 2, 1};
420 rb.Push(RESULT_SUCCESS); 463 rb.Push(RESULT_SUCCESS);
421 rb.PushCopyObjects(event); 464 rb.PushCopyObjects(msg_queue->GetOperationModeChangedEvent());
422 465
423 LOG_WARNING(Service_AM, "(STUBBED) called"); 466 LOG_DEBUG(Service_AM, "called");
424} 467}
425 468
426void ICommonStateGetter::GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx) { 469void ICommonStateGetter::GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx) {
@@ -444,7 +487,7 @@ void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
444 rb.Push(RESULT_SUCCESS); 487 rb.Push(RESULT_SUCCESS);
445 rb.Push(static_cast<u8>(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld)); 488 rb.Push(static_cast<u8>(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld));
446 489
447 LOG_WARNING(Service_AM, "(STUBBED) called"); 490 LOG_DEBUG(Service_AM, "called");
448} 491}
449 492
450void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) { 493void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
@@ -454,7 +497,7 @@ void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
454 rb.Push(static_cast<u32>(use_docked_mode ? APM::PerformanceMode::Docked 497 rb.Push(static_cast<u32>(use_docked_mode ? APM::PerformanceMode::Docked
455 : APM::PerformanceMode::Handheld)); 498 : APM::PerformanceMode::Handheld));
456 499
457 LOG_WARNING(Service_AM, "(STUBBED) called"); 500 LOG_DEBUG(Service_AM, "called");
458} 501}
459 502
460class IStorageAccessor final : public ServiceFramework<IStorageAccessor> { 503class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
@@ -840,8 +883,12 @@ void IApplicationFunctions::GetPseudoDeviceId(Kernel::HLERequestContext& ctx) {
840 883
841void InstallInterfaces(SM::ServiceManager& service_manager, 884void InstallInterfaces(SM::ServiceManager& service_manager,
842 std::shared_ptr<NVFlinger::NVFlinger> nvflinger) { 885 std::shared_ptr<NVFlinger::NVFlinger> nvflinger) {
843 std::make_shared<AppletAE>(nvflinger)->InstallAsService(service_manager); 886 auto message_queue = std::make_shared<AppletMessageQueue>();
844 std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager); 887 message_queue->PushMessage(
888 AppletMessageQueue::AppletMessage::FocusStateChanged); // Needed on game boot
889
890 std::make_shared<AppletAE>(nvflinger, message_queue)->InstallAsService(service_manager);
891 std::make_shared<AppletOE>(nvflinger, message_queue)->InstallAsService(service_manager);
845 std::make_shared<IdleSys>()->InstallAsService(service_manager); 892 std::make_shared<IdleSys>()->InstallAsService(service_manager);
846 std::make_shared<OMM>()->InstallAsService(service_manager); 893 std::make_shared<OMM>()->InstallAsService(service_manager);
847 std::make_shared<SPSM>()->InstallAsService(service_manager); 894 std::make_shared<SPSM>()->InstallAsService(service_manager);
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 095f94851..2f1c20bce 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -5,6 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <memory> 7#include <memory>
8#include <queue>
8#include "core/hle/service/service.h" 9#include "core/hle/service/service.h"
9 10
10namespace Kernel { 11namespace Kernel {
@@ -39,6 +40,31 @@ enum SystemLanguage {
39 TraditionalChinese = 16, 40 TraditionalChinese = 16,
40}; 41};
41 42
43class AppletMessageQueue {
44public:
45 enum class AppletMessage : u32 {
46 NoMessage = 0,
47 FocusStateChanged = 15,
48 OperationModeChanged = 30,
49 PerformanceModeChanged = 31,
50 };
51
52 AppletMessageQueue();
53 ~AppletMessageQueue();
54
55 const Kernel::SharedPtr<Kernel::Event>& GetMesssageRecieveEvent() const;
56 const Kernel::SharedPtr<Kernel::Event>& GetOperationModeChangedEvent() const;
57 void PushMessage(AppletMessage msg);
58 AppletMessage PopMessage();
59 std::size_t GetMessageCount() const;
60 void OperationModeChanged();
61
62private:
63 std::queue<AppletMessage> messages;
64 Kernel::SharedPtr<Kernel::Event> on_new_message;
65 Kernel::SharedPtr<Kernel::Event> on_operation_mode_changed;
66};
67
42class IWindowController final : public ServiceFramework<IWindowController> { 68class IWindowController final : public ServiceFramework<IWindowController> {
43public: 69public:
44 IWindowController(); 70 IWindowController();
@@ -102,7 +128,7 @@ private:
102 128
103class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> { 129class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {
104public: 130public:
105 ICommonStateGetter(); 131 explicit ICommonStateGetter(std::shared_ptr<AppletMessageQueue> msg_queue);
106 ~ICommonStateGetter() override; 132 ~ICommonStateGetter() override;
107 133
108private: 134private:
@@ -126,6 +152,7 @@ private:
126 void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx); 152 void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx);
127 153
128 Kernel::SharedPtr<Kernel::Event> event; 154 Kernel::SharedPtr<Kernel::Event> event;
155 std::shared_ptr<AppletMessageQueue> msg_queue;
129}; 156};
130 157
131class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> { 158class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> {
diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp
index 68ea778e8..ec93e3529 100644
--- a/src/core/hle/service/am/applet_ae.cpp
+++ b/src/core/hle/service/am/applet_ae.cpp
@@ -12,8 +12,10 @@ namespace Service::AM {
12 12
13class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> { 13class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> {
14public: 14public:
15 explicit ILibraryAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) 15 explicit ILibraryAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
16 : ServiceFramework("ILibraryAppletProxy"), nvflinger(std::move(nvflinger)) { 16 std::shared_ptr<AppletMessageQueue> msg_queue)
17 : ServiceFramework("ILibraryAppletProxy"), nvflinger(std::move(nvflinger)),
18 msg_queue(std::move(msg_queue)) {
17 static const FunctionInfo functions[] = { 19 static const FunctionInfo functions[] = {
18 {0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"}, 20 {0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"},
19 {1, &ILibraryAppletProxy::GetSelfController, "GetSelfController"}, 21 {1, &ILibraryAppletProxy::GetSelfController, "GetSelfController"},
@@ -32,7 +34,7 @@ private:
32 void GetCommonStateGetter(Kernel::HLERequestContext& ctx) { 34 void GetCommonStateGetter(Kernel::HLERequestContext& ctx) {
33 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 35 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
34 rb.Push(RESULT_SUCCESS); 36 rb.Push(RESULT_SUCCESS);
35 rb.PushIpcInterface<ICommonStateGetter>(); 37 rb.PushIpcInterface<ICommonStateGetter>(msg_queue);
36 LOG_DEBUG(Service_AM, "called"); 38 LOG_DEBUG(Service_AM, "called");
37 } 39 }
38 40
@@ -93,12 +95,15 @@ private:
93 } 95 }
94 96
95 std::shared_ptr<NVFlinger::NVFlinger> nvflinger; 97 std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
98 std::shared_ptr<AppletMessageQueue> msg_queue;
96}; 99};
97 100
98class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> { 101class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> {
99public: 102public:
100 explicit ISystemAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) 103 explicit ISystemAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
101 : ServiceFramework("ISystemAppletProxy"), nvflinger(std::move(nvflinger)) { 104 std::shared_ptr<AppletMessageQueue> msg_queue)
105 : ServiceFramework("ISystemAppletProxy"), nvflinger(std::move(nvflinger)),
106 msg_queue(std::move(msg_queue)) {
102 static const FunctionInfo functions[] = { 107 static const FunctionInfo functions[] = {
103 {0, &ISystemAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"}, 108 {0, &ISystemAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"},
104 {1, &ISystemAppletProxy::GetSelfController, "GetSelfController"}, 109 {1, &ISystemAppletProxy::GetSelfController, "GetSelfController"},
@@ -119,7 +124,7 @@ private:
119 void GetCommonStateGetter(Kernel::HLERequestContext& ctx) { 124 void GetCommonStateGetter(Kernel::HLERequestContext& ctx) {
120 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 125 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
121 rb.Push(RESULT_SUCCESS); 126 rb.Push(RESULT_SUCCESS);
122 rb.PushIpcInterface<ICommonStateGetter>(); 127 rb.PushIpcInterface<ICommonStateGetter>(msg_queue);
123 LOG_DEBUG(Service_AM, "called"); 128 LOG_DEBUG(Service_AM, "called");
124 } 129 }
125 130
@@ -186,31 +191,34 @@ private:
186 LOG_DEBUG(Service_AM, "called"); 191 LOG_DEBUG(Service_AM, "called");
187 } 192 }
188 std::shared_ptr<NVFlinger::NVFlinger> nvflinger; 193 std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
194 std::shared_ptr<AppletMessageQueue> msg_queue;
189}; 195};
190 196
191void AppletAE::OpenSystemAppletProxy(Kernel::HLERequestContext& ctx) { 197void AppletAE::OpenSystemAppletProxy(Kernel::HLERequestContext& ctx) {
192 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 198 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
193 rb.Push(RESULT_SUCCESS); 199 rb.Push(RESULT_SUCCESS);
194 rb.PushIpcInterface<ISystemAppletProxy>(nvflinger); 200 rb.PushIpcInterface<ISystemAppletProxy>(nvflinger, msg_queue);
195 LOG_DEBUG(Service_AM, "called"); 201 LOG_DEBUG(Service_AM, "called");
196} 202}
197 203
198void AppletAE::OpenLibraryAppletProxy(Kernel::HLERequestContext& ctx) { 204void AppletAE::OpenLibraryAppletProxy(Kernel::HLERequestContext& ctx) {
199 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 205 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
200 rb.Push(RESULT_SUCCESS); 206 rb.Push(RESULT_SUCCESS);
201 rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger); 207 rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger, msg_queue);
202 LOG_DEBUG(Service_AM, "called"); 208 LOG_DEBUG(Service_AM, "called");
203} 209}
204 210
205void AppletAE::OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx) { 211void AppletAE::OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx) {
206 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 212 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
207 rb.Push(RESULT_SUCCESS); 213 rb.Push(RESULT_SUCCESS);
208 rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger); 214 rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger, msg_queue);
209 LOG_DEBUG(Service_AM, "called"); 215 LOG_DEBUG(Service_AM, "called");
210} 216}
211 217
212AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) 218AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
213 : ServiceFramework("appletAE"), nvflinger(std::move(nvflinger)) { 219 std::shared_ptr<AppletMessageQueue> msg_queue)
220 : ServiceFramework("appletAE"), nvflinger(std::move(nvflinger)),
221 msg_queue(std::move(msg_queue)) {
214 // clang-format off 222 // clang-format off
215 static const FunctionInfo functions[] = { 223 static const FunctionInfo functions[] = {
216 {100, &AppletAE::OpenSystemAppletProxy, "OpenSystemAppletProxy"}, 224 {100, &AppletAE::OpenSystemAppletProxy, "OpenSystemAppletProxy"},
@@ -228,4 +236,8 @@ AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
228 236
229AppletAE::~AppletAE() = default; 237AppletAE::~AppletAE() = default;
230 238
239const std::shared_ptr<AppletMessageQueue>& AppletAE::GetMessageQueue() const {
240 return msg_queue;
241}
242
231} // namespace Service::AM 243} // namespace Service::AM
diff --git a/src/core/hle/service/am/applet_ae.h b/src/core/hle/service/am/applet_ae.h
index 1ed77baa4..902db2665 100644
--- a/src/core/hle/service/am/applet_ae.h
+++ b/src/core/hle/service/am/applet_ae.h
@@ -17,15 +17,19 @@ namespace AM {
17 17
18class AppletAE final : public ServiceFramework<AppletAE> { 18class AppletAE final : public ServiceFramework<AppletAE> {
19public: 19public:
20 explicit AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger); 20 explicit AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
21 std::shared_ptr<AppletMessageQueue> msg_queue);
21 ~AppletAE() override; 22 ~AppletAE() override;
22 23
24 const std::shared_ptr<AppletMessageQueue>& GetMessageQueue() const;
25
23private: 26private:
24 void OpenSystemAppletProxy(Kernel::HLERequestContext& ctx); 27 void OpenSystemAppletProxy(Kernel::HLERequestContext& ctx);
25 void OpenLibraryAppletProxy(Kernel::HLERequestContext& ctx); 28 void OpenLibraryAppletProxy(Kernel::HLERequestContext& ctx);
26 void OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx); 29 void OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx);
27 30
28 std::shared_ptr<NVFlinger::NVFlinger> nvflinger; 31 std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
32 std::shared_ptr<AppletMessageQueue> msg_queue;
29}; 33};
30 34
31} // namespace AM 35} // namespace AM
diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp
index 60717afd9..20c8d5fff 100644
--- a/src/core/hle/service/am/applet_oe.cpp
+++ b/src/core/hle/service/am/applet_oe.cpp
@@ -12,8 +12,10 @@ namespace Service::AM {
12 12
13class IApplicationProxy final : public ServiceFramework<IApplicationProxy> { 13class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
14public: 14public:
15 explicit IApplicationProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) 15 explicit IApplicationProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
16 : ServiceFramework("IApplicationProxy"), nvflinger(std::move(nvflinger)) { 16 std::shared_ptr<AppletMessageQueue> msg_queue)
17 : ServiceFramework("IApplicationProxy"), nvflinger(std::move(nvflinger)),
18 msg_queue(std::move(msg_queue)) {
17 // clang-format off 19 // clang-format off
18 static const FunctionInfo functions[] = { 20 static const FunctionInfo functions[] = {
19 {0, &IApplicationProxy::GetCommonStateGetter, "GetCommonStateGetter"}, 21 {0, &IApplicationProxy::GetCommonStateGetter, "GetCommonStateGetter"},
@@ -70,7 +72,7 @@ private:
70 void GetCommonStateGetter(Kernel::HLERequestContext& ctx) { 72 void GetCommonStateGetter(Kernel::HLERequestContext& ctx) {
71 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 73 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
72 rb.Push(RESULT_SUCCESS); 74 rb.Push(RESULT_SUCCESS);
73 rb.PushIpcInterface<ICommonStateGetter>(); 75 rb.PushIpcInterface<ICommonStateGetter>(msg_queue);
74 LOG_DEBUG(Service_AM, "called"); 76 LOG_DEBUG(Service_AM, "called");
75 } 77 }
76 78
@@ -89,17 +91,20 @@ private:
89 } 91 }
90 92
91 std::shared_ptr<NVFlinger::NVFlinger> nvflinger; 93 std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
94 std::shared_ptr<AppletMessageQueue> msg_queue;
92}; 95};
93 96
94void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) { 97void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) {
95 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 98 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
96 rb.Push(RESULT_SUCCESS); 99 rb.Push(RESULT_SUCCESS);
97 rb.PushIpcInterface<IApplicationProxy>(nvflinger); 100 rb.PushIpcInterface<IApplicationProxy>(nvflinger, msg_queue);
98 LOG_DEBUG(Service_AM, "called"); 101 LOG_DEBUG(Service_AM, "called");
99} 102}
100 103
101AppletOE::AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger) 104AppletOE::AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
102 : ServiceFramework("appletOE"), nvflinger(std::move(nvflinger)) { 105 std::shared_ptr<AppletMessageQueue> msg_queue)
106 : ServiceFramework("appletOE"), nvflinger(std::move(nvflinger)),
107 msg_queue(std::move(msg_queue)) {
103 static const FunctionInfo functions[] = { 108 static const FunctionInfo functions[] = {
104 {0, &AppletOE::OpenApplicationProxy, "OpenApplicationProxy"}, 109 {0, &AppletOE::OpenApplicationProxy, "OpenApplicationProxy"},
105 }; 110 };
@@ -108,4 +113,8 @@ AppletOE::AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
108 113
109AppletOE::~AppletOE() = default; 114AppletOE::~AppletOE() = default;
110 115
116const std::shared_ptr<AppletMessageQueue>& AppletOE::GetMessageQueue() const {
117 return msg_queue;
118}
119
111} // namespace Service::AM 120} // namespace Service::AM
diff --git a/src/core/hle/service/am/applet_oe.h b/src/core/hle/service/am/applet_oe.h
index 60cfdfd9d..bbd0108ef 100644
--- a/src/core/hle/service/am/applet_oe.h
+++ b/src/core/hle/service/am/applet_oe.h
@@ -17,13 +17,17 @@ namespace AM {
17 17
18class AppletOE final : public ServiceFramework<AppletOE> { 18class AppletOE final : public ServiceFramework<AppletOE> {
19public: 19public:
20 explicit AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger); 20 explicit AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
21 std::shared_ptr<AppletMessageQueue> msg_queue);
21 ~AppletOE() override; 22 ~AppletOE() override;
22 23
24 const std::shared_ptr<AppletMessageQueue>& GetMessageQueue() const;
25
23private: 26private:
24 void OpenApplicationProxy(Kernel::HLERequestContext& ctx); 27 void OpenApplicationProxy(Kernel::HLERequestContext& ctx);
25 28
26 std::shared_ptr<NVFlinger::NVFlinger> nvflinger; 29 std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
30 std::shared_ptr<AppletMessageQueue> msg_queue;
27}; 31};
28 32
29} // namespace AM 33} // namespace AM
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 0b1cc1290..a780215c1 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -21,6 +21,7 @@ add_library(video_core STATIC
21 macro_interpreter.h 21 macro_interpreter.h
22 memory_manager.cpp 22 memory_manager.cpp
23 memory_manager.h 23 memory_manager.h
24 rasterizer_cache.cpp
24 rasterizer_cache.h 25 rasterizer_cache.h
25 rasterizer_interface.h 26 rasterizer_interface.h
26 renderer_base.cpp 27 renderer_base.cpp
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 2cd595f26..5ae836aca 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -108,8 +108,16 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
108 debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandLoaded, nullptr); 108 debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandLoaded, nullptr);
109 } 109 }
110 110
111 u32 old = regs.reg_array[method];
111 regs.reg_array[method] = value; 112 regs.reg_array[method] = value;
112 113
114 if (value != old) {
115 if (method >= MAXWELL3D_REG_INDEX(vertex_attrib_format) &&
116 method < MAXWELL3D_REG_INDEX(vertex_attrib_format) + regs.vertex_attrib_format.size()) {
117 dirty_flags.vertex_attrib_format = true;
118 }
119 }
120
113 switch (method) { 121 switch (method) {
114 case MAXWELL3D_REG_INDEX(macros.data): { 122 case MAXWELL3D_REG_INDEX(macros.data): {
115 ProcessMacroUpload(value); 123 ProcessMacroUpload(value);
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 0509ba3a2..557795d0f 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -1004,6 +1004,12 @@ public:
1004 State state{}; 1004 State state{};
1005 MemoryManager& memory_manager; 1005 MemoryManager& memory_manager;
1006 1006
1007 struct DirtyFlags {
1008 bool vertex_attrib_format = true;
1009 };
1010
1011 DirtyFlags dirty_flags;
1012
1007 /// Reads a register value located at the input method address 1013 /// Reads a register value located at the input method address
1008 u32 GetRegisterValue(u32 method) const; 1014 u32 GetRegisterValue(u32 method) const;
1009 1015
diff --git a/src/video_core/rasterizer_cache.cpp b/src/video_core/rasterizer_cache.cpp
new file mode 100644
index 000000000..093b2cdf4
--- /dev/null
+++ b/src/video_core/rasterizer_cache.cpp
@@ -0,0 +1,7 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "video_core/rasterizer_cache.h"
6
7RasterizerCacheObject::~RasterizerCacheObject() = default;
diff --git a/src/video_core/rasterizer_cache.h b/src/video_core/rasterizer_cache.h
index 0a3b3951e..6d41321fa 100644
--- a/src/video_core/rasterizer_cache.h
+++ b/src/video_core/rasterizer_cache.h
@@ -10,13 +10,13 @@
10#include <boost/range/iterator_range_core.hpp> 10#include <boost/range/iterator_range_core.hpp>
11 11
12#include "common/common_types.h" 12#include "common/common_types.h"
13#include "core/core.h"
14#include "core/settings.h" 13#include "core/settings.h"
15#include "video_core/rasterizer_interface.h" 14#include "video_core/rasterizer_interface.h"
16#include "video_core/renderer_base.h"
17 15
18class RasterizerCacheObject { 16class RasterizerCacheObject {
19public: 17public:
18 virtual ~RasterizerCacheObject();
19
20 /// Gets the address of the shader in guest memory, required for cache management 20 /// Gets the address of the shader in guest memory, required for cache management
21 virtual VAddr GetAddr() const = 0; 21 virtual VAddr GetAddr() const = 0;
22 22
@@ -64,6 +64,8 @@ class RasterizerCache : NonCopyable {
64 friend class RasterizerCacheObject; 64 friend class RasterizerCacheObject;
65 65
66public: 66public:
67 explicit RasterizerCache(VideoCore::RasterizerInterface& rasterizer) : rasterizer{rasterizer} {}
68
67 /// Write any cached resources overlapping the specified region back to memory 69 /// Write any cached resources overlapping the specified region back to memory
68 void FlushRegion(Tegra::GPUVAddr addr, size_t size) { 70 void FlushRegion(Tegra::GPUVAddr addr, size_t size) {
69 const auto& objects{GetSortedObjectsFromRegion(addr, size)}; 71 const auto& objects{GetSortedObjectsFromRegion(addr, size)};
@@ -109,14 +111,12 @@ protected:
109 void Register(const T& object) { 111 void Register(const T& object) {
110 object->SetIsRegistered(true); 112 object->SetIsRegistered(true);
111 object_cache.add({GetInterval(object), ObjectSet{object}}); 113 object_cache.add({GetInterval(object), ObjectSet{object}});
112 auto& rasterizer = Core::System::GetInstance().Renderer().Rasterizer();
113 rasterizer.UpdatePagesCachedCount(object->GetAddr(), object->GetSizeInBytes(), 1); 114 rasterizer.UpdatePagesCachedCount(object->GetAddr(), object->GetSizeInBytes(), 1);
114 } 115 }
115 116
116 /// Unregisters an object from the cache 117 /// Unregisters an object from the cache
117 void Unregister(const T& object) { 118 void Unregister(const T& object) {
118 object->SetIsRegistered(false); 119 object->SetIsRegistered(false);
119 auto& rasterizer = Core::System::GetInstance().Renderer().Rasterizer();
120 rasterizer.UpdatePagesCachedCount(object->GetAddr(), object->GetSizeInBytes(), -1); 120 rasterizer.UpdatePagesCachedCount(object->GetAddr(), object->GetSizeInBytes(), -1);
121 121
122 // Only flush if use_accurate_gpu_emulation is enabled, as it incurs a performance hit 122 // Only flush if use_accurate_gpu_emulation is enabled, as it incurs a performance hit
@@ -177,4 +177,5 @@ private:
177 177
178 ObjectCache object_cache; ///< Cache of objects 178 ObjectCache object_cache; ///< Cache of objects
179 u64 modified_ticks{}; ///< Counter of cache state ticks, used for in-order flushing 179 u64 modified_ticks{}; ///< Counter of cache state ticks, used for in-order flushing
180 VideoCore::RasterizerInterface& rasterizer;
180}; 181};
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index 41a54b3e7..075192c3f 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -9,10 +9,12 @@
9#include "core/core.h" 9#include "core/core.h"
10#include "core/memory.h" 10#include "core/memory.h"
11#include "video_core/renderer_opengl/gl_buffer_cache.h" 11#include "video_core/renderer_opengl/gl_buffer_cache.h"
12#include "video_core/renderer_opengl/gl_rasterizer.h"
12 13
13namespace OpenGL { 14namespace OpenGL {
14 15
15OGLBufferCache::OGLBufferCache(std::size_t size) : stream_buffer(GL_ARRAY_BUFFER, size) {} 16OGLBufferCache::OGLBufferCache(RasterizerOpenGL& rasterizer, std::size_t size)
17 : RasterizerCache{rasterizer}, stream_buffer(GL_ARRAY_BUFFER, size) {}
16 18
17GLintptr OGLBufferCache::UploadMemory(Tegra::GPUVAddr gpu_addr, std::size_t size, 19GLintptr OGLBufferCache::UploadMemory(Tegra::GPUVAddr gpu_addr, std::size_t size,
18 std::size_t alignment, bool cache) { 20 std::size_t alignment, bool cache) {
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h
index be29dc8be..91fca3f6c 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.h
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.h
@@ -15,6 +15,8 @@
15 15
16namespace OpenGL { 16namespace OpenGL {
17 17
18class RasterizerOpenGL;
19
18struct CachedBufferEntry final : public RasterizerCacheObject { 20struct CachedBufferEntry final : public RasterizerCacheObject {
19 VAddr GetAddr() const override { 21 VAddr GetAddr() const override {
20 return addr; 22 return addr;
@@ -35,7 +37,7 @@ struct CachedBufferEntry final : public RasterizerCacheObject {
35 37
36class OGLBufferCache final : public RasterizerCache<std::shared_ptr<CachedBufferEntry>> { 38class OGLBufferCache final : public RasterizerCache<std::shared_ptr<CachedBufferEntry>> {
37public: 39public:
38 explicit OGLBufferCache(std::size_t size); 40 explicit OGLBufferCache(RasterizerOpenGL& rasterizer, std::size_t size);
39 41
40 /// Uploads data from a guest GPU address. Returns host's buffer offset where it's been 42 /// Uploads data from a guest GPU address. Returns host's buffer offset where it's been
41 /// allocated. 43 /// allocated.
diff --git a/src/video_core/renderer_opengl/gl_primitive_assembler.cpp b/src/video_core/renderer_opengl/gl_primitive_assembler.cpp
index 741f14bc3..d9ed08437 100644
--- a/src/video_core/renderer_opengl/gl_primitive_assembler.cpp
+++ b/src/video_core/renderer_opengl/gl_primitive_assembler.cpp
@@ -6,6 +6,7 @@
6#include <array> 6#include <array>
7#include "common/assert.h" 7#include "common/assert.h"
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "core/core.h"
9#include "core/memory.h" 10#include "core/memory.h"
10#include "video_core/renderer_opengl/gl_buffer_cache.h" 11#include "video_core/renderer_opengl/gl_buffer_cache.h"
11#include "video_core/renderer_opengl/gl_primitive_assembler.h" 12#include "video_core/renderer_opengl/gl_primitive_assembler.h"
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index bb263b6aa..a404764f5 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -33,7 +33,8 @@ using Maxwell = Tegra::Engines::Maxwell3D::Regs;
33using PixelFormat = VideoCore::Surface::PixelFormat; 33using PixelFormat = VideoCore::Surface::PixelFormat;
34using SurfaceType = VideoCore::Surface::SurfaceType; 34using SurfaceType = VideoCore::Surface::SurfaceType;
35 35
36MICROPROFILE_DEFINE(OpenGL_VAO, "OpenGL", "Vertex Array Setup", MP_RGB(128, 128, 192)); 36MICROPROFILE_DEFINE(OpenGL_VAO, "OpenGL", "Vertex Format Setup", MP_RGB(128, 128, 192));
37MICROPROFILE_DEFINE(OpenGL_VB, "OpenGL", "Vertex Buffer Setup", MP_RGB(128, 128, 192));
37MICROPROFILE_DEFINE(OpenGL_Shader, "OpenGL", "Shader Setup", MP_RGB(128, 128, 192)); 38MICROPROFILE_DEFINE(OpenGL_Shader, "OpenGL", "Shader Setup", MP_RGB(128, 128, 192));
38MICROPROFILE_DEFINE(OpenGL_UBO, "OpenGL", "Const Buffer Setup", MP_RGB(128, 128, 192)); 39MICROPROFILE_DEFINE(OpenGL_UBO, "OpenGL", "Const Buffer Setup", MP_RGB(128, 128, 192));
39MICROPROFILE_DEFINE(OpenGL_Index, "OpenGL", "Index Buffer Setup", MP_RGB(128, 128, 192)); 40MICROPROFILE_DEFINE(OpenGL_Index, "OpenGL", "Index Buffer Setup", MP_RGB(128, 128, 192));
@@ -79,7 +80,8 @@ struct DrawParameters {
79}; 80};
80 81
81RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window, ScreenInfo& info) 82RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window, ScreenInfo& info)
82 : emu_window{window}, screen_info{info}, buffer_cache(STREAM_BUFFER_SIZE) { 83 : res_cache{*this}, shader_cache{*this}, emu_window{window}, screen_info{info},
84 buffer_cache(*this, STREAM_BUFFER_SIZE) {
83 // Create sampler objects 85 // Create sampler objects
84 for (std::size_t i = 0; i < texture_samplers.size(); ++i) { 86 for (std::size_t i = 0; i < texture_samplers.size(); ++i) {
85 texture_samplers[i].Create(); 87 texture_samplers[i].Create();
@@ -122,11 +124,16 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window, ScreenInfo
122 124
123RasterizerOpenGL::~RasterizerOpenGL() {} 125RasterizerOpenGL::~RasterizerOpenGL() {}
124 126
125void RasterizerOpenGL::SetupVertexArrays() { 127void RasterizerOpenGL::SetupVertexFormat() {
126 MICROPROFILE_SCOPE(OpenGL_VAO); 128 auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
127 const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
128 const auto& regs = gpu.regs; 129 const auto& regs = gpu.regs;
129 130
131 if (!gpu.dirty_flags.vertex_attrib_format)
132 return;
133 gpu.dirty_flags.vertex_attrib_format = false;
134
135 MICROPROFILE_SCOPE(OpenGL_VAO);
136
130 auto [iter, is_cache_miss] = vertex_array_cache.try_emplace(regs.vertex_attrib_format); 137 auto [iter, is_cache_miss] = vertex_array_cache.try_emplace(regs.vertex_attrib_format);
131 auto& VAO = iter->second; 138 auto& VAO = iter->second;
132 139
@@ -175,8 +182,13 @@ void RasterizerOpenGL::SetupVertexArrays() {
175 } 182 }
176 } 183 }
177 state.draw.vertex_array = VAO.handle; 184 state.draw.vertex_array = VAO.handle;
178 state.draw.vertex_buffer = buffer_cache.GetHandle();
179 state.Apply(); 185 state.Apply();
186}
187
188void RasterizerOpenGL::SetupVertexBuffer() {
189 MICROPROFILE_SCOPE(OpenGL_VB);
190 const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
191 const auto& regs = gpu.regs;
180 192
181 // Upload all guest vertex arrays sequentially to our buffer 193 // Upload all guest vertex arrays sequentially to our buffer
182 for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { 194 for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) {
@@ -203,6 +215,9 @@ void RasterizerOpenGL::SetupVertexArrays() {
203 glVertexBindingDivisor(index, 0); 215 glVertexBindingDivisor(index, 0);
204 } 216 }
205 } 217 }
218
219 // Implicit set by glBindVertexBuffer. Stupid glstate handling...
220 state.draw.vertex_buffer = buffer_cache.GetHandle();
206} 221}
207 222
208DrawParameters RasterizerOpenGL::SetupDraw() { 223DrawParameters RasterizerOpenGL::SetupDraw() {
@@ -620,7 +635,8 @@ void RasterizerOpenGL::DrawArrays() {
620 635
621 buffer_cache.Map(buffer_size); 636 buffer_cache.Map(buffer_size);
622 637
623 SetupVertexArrays(); 638 SetupVertexFormat();
639 SetupVertexBuffer();
624 DrawParameters params = SetupDraw(); 640 DrawParameters params = SetupDraw();
625 SetupShaders(params.primitive_mode); 641 SetupShaders(params.primitive_mode);
626 642
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 60e783803..5eee5f088 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -207,7 +207,8 @@ private:
207 207
208 std::size_t CalculateIndexBufferSize() const; 208 std::size_t CalculateIndexBufferSize() const;
209 209
210 void SetupVertexArrays(); 210 void SetupVertexFormat();
211 void SetupVertexBuffer();
211 212
212 DrawParameters SetupDraw(); 213 DrawParameters SetupDraw();
213 214
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 49d63e6f3..c8864cce8 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -15,6 +15,7 @@
15#include "core/memory.h" 15#include "core/memory.h"
16#include "core/settings.h" 16#include "core/settings.h"
17#include "video_core/engines/maxwell_3d.h" 17#include "video_core/engines/maxwell_3d.h"
18#include "video_core/renderer_opengl/gl_rasterizer.h"
18#include "video_core/renderer_opengl/gl_rasterizer_cache.h" 19#include "video_core/renderer_opengl/gl_rasterizer_cache.h"
19#include "video_core/renderer_opengl/gl_state.h" 20#include "video_core/renderer_opengl/gl_state.h"
20#include "video_core/renderer_opengl/utils.h" 21#include "video_core/renderer_opengl/utils.h"
@@ -1172,7 +1173,8 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle
1172 UploadGLMipmapTexture(i, read_fb_handle, draw_fb_handle); 1173 UploadGLMipmapTexture(i, read_fb_handle, draw_fb_handle);
1173} 1174}
1174 1175
1175RasterizerCacheOpenGL::RasterizerCacheOpenGL() { 1176RasterizerCacheOpenGL::RasterizerCacheOpenGL(RasterizerOpenGL& rasterizer)
1177 : RasterizerCache{rasterizer} {
1176 read_framebuffer.Create(); 1178 read_framebuffer.Create();
1177 draw_framebuffer.Create(); 1179 draw_framebuffer.Create();
1178 copy_pbo.Create(); 1180 copy_pbo.Create();
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index c0b6bc4e6..494f6b903 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -264,6 +264,8 @@ struct hash<SurfaceReserveKey> {
264 264
265namespace OpenGL { 265namespace OpenGL {
266 266
267class RasterizerOpenGL;
268
267class CachedSurface final : public RasterizerCacheObject { 269class CachedSurface final : public RasterizerCacheObject {
268public: 270public:
269 CachedSurface(const SurfaceParams& params); 271 CachedSurface(const SurfaceParams& params);
@@ -311,7 +313,7 @@ private:
311 313
312class RasterizerCacheOpenGL final : public RasterizerCache<Surface> { 314class RasterizerCacheOpenGL final : public RasterizerCache<Surface> {
313public: 315public:
314 RasterizerCacheOpenGL(); 316 explicit RasterizerCacheOpenGL(RasterizerOpenGL& rasterizer);
315 317
316 /// Get a surface based on the texture configuration 318 /// Get a surface based on the texture configuration
317 Surface GetTextureSurface(const Tegra::Texture::FullTextureInfo& config, 319 Surface GetTextureSurface(const Tegra::Texture::FullTextureInfo& config,
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 31ccf4ab8..a85a7c0c5 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -6,10 +6,10 @@
6#include "core/core.h" 6#include "core/core.h"
7#include "core/memory.h" 7#include "core/memory.h"
8#include "video_core/engines/maxwell_3d.h" 8#include "video_core/engines/maxwell_3d.h"
9#include "video_core/renderer_opengl/gl_rasterizer.h"
9#include "video_core/renderer_opengl/gl_shader_cache.h" 10#include "video_core/renderer_opengl/gl_shader_cache.h"
10#include "video_core/renderer_opengl/gl_shader_manager.h" 11#include "video_core/renderer_opengl/gl_shader_manager.h"
11#include "video_core/renderer_opengl/utils.h" 12#include "video_core/renderer_opengl/utils.h"
12#include "video_core/utils.h"
13 13
14namespace OpenGL { 14namespace OpenGL {
15 15
@@ -139,6 +139,8 @@ GLuint CachedShader::LazyGeometryProgram(OGLProgram& target_program,
139 return target_program.handle; 139 return target_program.handle;
140}; 140};
141 141
142ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer) : RasterizerCache{rasterizer} {}
143
142Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) { 144Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) {
143 const VAddr program_addr{GetShaderAddress(program)}; 145 const VAddr program_addr{GetShaderAddress(program)};
144 146
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h
index 8fd0b7e88..ffbf21831 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.h
+++ b/src/video_core/renderer_opengl/gl_shader_cache.h
@@ -16,6 +16,8 @@
16namespace OpenGL { 16namespace OpenGL {
17 17
18class CachedShader; 18class CachedShader;
19class RasterizerOpenGL;
20
19using Shader = std::shared_ptr<CachedShader>; 21using Shader = std::shared_ptr<CachedShader>;
20using Maxwell = Tegra::Engines::Maxwell3D::Regs; 22using Maxwell = Tegra::Engines::Maxwell3D::Regs;
21 23
@@ -105,6 +107,8 @@ private:
105 107
106class ShaderCacheOpenGL final : public RasterizerCache<Shader> { 108class ShaderCacheOpenGL final : public RasterizerCache<Shader> {
107public: 109public:
110 explicit ShaderCacheOpenGL(RasterizerOpenGL& rasterizer);
111
108 /// Gets the current specified shader stage program 112 /// Gets the current specified shader stage program
109 Shader GetStageProgram(Maxwell::ShaderProgram program); 113 Shader GetStageProgram(Maxwell::ShaderProgram program);
110}; 114};
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index bce7465b5..5fde22ad4 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -2746,12 +2746,12 @@ private:
2746 } 2746 }
2747 case 3: { 2747 case 3: {
2748 if (is_array) { 2748 if (is_array) {
2749 UNIMPLEMENTED_MSG("3-coordinate arrays not fully implemented"); 2749 const std::string index = regs.GetRegisterAsInteger(instr.gpr8);
2750 const std::string x = regs.GetRegisterAsFloat(instr.gpr8); 2750 const std::string x = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
2751 const std::string y = regs.GetRegisterAsFloat(instr.gpr20); 2751 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 2);
2752 coord = "vec2 coords = vec2(" + x + ", " + y + ");"; 2752 const std::string z = regs.GetRegisterAsFloat(instr.gpr20);
2753 texture_type = Tegra::Shader::TextureType::Texture2D; 2753 coord =
2754 is_array = false; 2754 "vec4 coords = vec4(" + x + ", " + y + ", " + z + ", " + index + ");";
2755 } else { 2755 } else {
2756 const std::string x = regs.GetRegisterAsFloat(instr.gpr8); 2756 const std::string x = regs.GetRegisterAsFloat(instr.gpr8);
2757 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1); 2757 const std::string y = regs.GetRegisterAsFloat(instr.gpr8.Value() + 1);
@@ -2781,7 +2781,11 @@ private:
2781 break; 2781 break;
2782 } 2782 }
2783 case Tegra::Shader::TextureProcessMode::LZ: { 2783 case Tegra::Shader::TextureProcessMode::LZ: {
2784 texture = "textureLod(" + sampler + ", coords, 0.0)"; 2784 if (depth_compare && is_array) {
2785 texture = "texture(" + sampler + ", coords)";
2786 } else {
2787 texture = "textureLod(" + sampler + ", coords, 0.0)";
2788 }
2785 break; 2789 break;
2786 } 2790 }
2787 case Tegra::Shader::TextureProcessMode::LL: { 2791 case Tegra::Shader::TextureProcessMode::LL: {
diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp
index 537d6e576..b322258a0 100644
--- a/src/yuzu/configuration/configure_general.cpp
+++ b/src/yuzu/configuration/configure_general.cpp
@@ -3,6 +3,10 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hle/service/am/am.h"
7#include "core/hle/service/am/applet_ae.h"
8#include "core/hle/service/am/applet_oe.h"
9#include "core/hle/service/sm/sm.h"
6#include "core/settings.h" 10#include "core/settings.h"
7#include "ui_configure_general.h" 11#include "ui_configure_general.h"
8#include "yuzu/configuration/configure_general.h" 12#include "yuzu/configuration/configure_general.h"
@@ -20,7 +24,6 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
20 this->setConfiguration(); 24 this->setConfiguration();
21 25
22 ui->use_cpu_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn()); 26 ui->use_cpu_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn());
23 ui->use_docked_mode->setEnabled(!Core::System::GetInstance().IsPoweredOn());
24} 27}
25 28
26ConfigureGeneral::~ConfigureGeneral() = default; 29ConfigureGeneral::~ConfigureGeneral() = default;
@@ -38,6 +41,30 @@ void ConfigureGeneral::PopulateHotkeyList(const HotkeyRegistry& registry) {
38 ui->widget->Populate(registry); 41 ui->widget->Populate(registry);
39} 42}
40 43
44void ConfigureGeneral::OnDockedModeChanged(bool last_state, bool new_state) {
45 if (last_state == new_state) {
46 return;
47 }
48
49 Core::System& system{Core::System::GetInstance()};
50 Service::SM::ServiceManager& sm = system.ServiceManager();
51
52 // Message queue is shared between these services, we just need to signal an operation
53 // change to one and it will handle both automatically
54 auto applet_oe = sm.GetService<Service::AM::AppletOE>("appletOE");
55 auto applet_ae = sm.GetService<Service::AM::AppletAE>("appletAE");
56 bool has_signalled = false;
57
58 if (applet_oe != nullptr) {
59 applet_oe->GetMessageQueue()->OperationModeChanged();
60 has_signalled = true;
61 }
62
63 if (applet_ae != nullptr && !has_signalled) {
64 applet_ae->GetMessageQueue()->OperationModeChanged();
65 }
66}
67
41void ConfigureGeneral::applyConfiguration() { 68void ConfigureGeneral::applyConfiguration() {
42 UISettings::values.gamedir_deepscan = ui->toggle_deepscan->isChecked(); 69 UISettings::values.gamedir_deepscan = ui->toggle_deepscan->isChecked();
43 UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked(); 70 UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked();
@@ -45,6 +72,9 @@ void ConfigureGeneral::applyConfiguration() {
45 ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString(); 72 ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString();
46 73
47 Settings::values.use_cpu_jit = ui->use_cpu_jit->isChecked(); 74 Settings::values.use_cpu_jit = ui->use_cpu_jit->isChecked();
75 const bool pre_docked_mode = Settings::values.use_docked_mode;
48 Settings::values.use_docked_mode = ui->use_docked_mode->isChecked(); 76 Settings::values.use_docked_mode = ui->use_docked_mode->isChecked();
77 OnDockedModeChanged(pre_docked_mode, Settings::values.use_docked_mode);
78
49 Settings::values.enable_nfc = ui->enable_nfc->isChecked(); 79 Settings::values.enable_nfc = ui->enable_nfc->isChecked();
50} 80}
diff --git a/src/yuzu/configuration/configure_general.h b/src/yuzu/configuration/configure_general.h
index 4770034cc..2210d48da 100644
--- a/src/yuzu/configuration/configure_general.h
+++ b/src/yuzu/configuration/configure_general.h
@@ -25,6 +25,7 @@ public:
25 25
26private: 26private:
27 void setConfiguration(); 27 void setConfiguration();
28 void OnDockedModeChanged(bool last_state, bool new_state);
28 29
29 std::unique_ptr<Ui::ConfigureGeneral> ui; 30 std::unique_ptr<Ui::ConfigureGeneral> ui;
30}; 31};