early-access version 2975
This commit is contained in:
parent
189c89d2e7
commit
be118d4809
8 changed files with 71 additions and 30 deletions
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 2974.
|
This is the source code for early-access 2975.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "core/hle/service/nvflinger/ui/graphic_buffer.h"
|
#include "core/hle/service/nvflinger/ui/graphic_buffer.h"
|
||||||
#include "core/hle/service/vi/display/vi_display.h"
|
#include "core/hle/service/vi/display/vi_display.h"
|
||||||
#include "core/hle/service/vi/layer/vi_layer.h"
|
#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/gpu.h"
|
||||||
#include "video_core/host1x/host1x.h"
|
#include "video_core/host1x/host1x.h"
|
||||||
#include "video_core/host1x/syncpoint_manager.h"
|
#include "video_core/host1x/syncpoint_manager.h"
|
||||||
|
@ -170,15 +171,15 @@ std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) {
|
||||||
return layer->GetBinderId();
|
return layer->GetBinderId();
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::KReadableEvent* NVFlinger::FindVsyncEvent(u64 display_id) {
|
ResultVal<Kernel::KReadableEvent*> NVFlinger::FindVsyncEvent(u64 display_id) {
|
||||||
const auto lock_guard = Lock();
|
const auto lock_guard = Lock();
|
||||||
auto* const display = FindDisplay(display_id);
|
auto* const display = FindDisplay(display_id);
|
||||||
|
|
||||||
if (display == nullptr) {
|
if (display == nullptr) {
|
||||||
return nullptr;
|
return VI::ResultNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &display->GetVSyncEvent();
|
return display->GetVSyncEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
VI::Display* NVFlinger::FindDisplay(u64 display_id) {
|
VI::Display* NVFlinger::FindDisplay(u64 display_id) {
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "core/hle/result.h"
|
||||||
#include "core/hle/service/kernel_helpers.h"
|
#include "core/hle/service/kernel_helpers.h"
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
@ -71,8 +72,9 @@ public:
|
||||||
|
|
||||||
/// Gets the vsync event for the specified display.
|
/// Gets the vsync event for the specified display.
|
||||||
///
|
///
|
||||||
/// If an invalid display ID is provided, then nullptr is returned.
|
/// If an invalid display ID is provided, then VI::ResultNotFound is returned.
|
||||||
[[nodiscard]] Kernel::KReadableEvent* FindVsyncEvent(u64 display_id);
|
/// If the vsync event has already been retrieved, then VI::ResultPermissionDenied is returned.
|
||||||
|
[[nodiscard]] ResultVal<Kernel::KReadableEvent*> FindVsyncEvent(u64 display_id);
|
||||||
|
|
||||||
/// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when
|
/// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when
|
||||||
/// finished.
|
/// finished.
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "core/hle/service/nvflinger/hos_binder_driver_server.h"
|
#include "core/hle/service/nvflinger/hos_binder_driver_server.h"
|
||||||
#include "core/hle/service/vi/display/vi_display.h"
|
#include "core/hle/service/vi/display/vi_display.h"
|
||||||
#include "core/hle/service/vi/layer/vi_layer.h"
|
#include "core/hle/service/vi/layer/vi_layer.h"
|
||||||
|
#include "core/hle/service/vi/vi_results.h"
|
||||||
|
|
||||||
namespace Service::VI {
|
namespace Service::VI {
|
||||||
|
|
||||||
|
@ -58,8 +59,18 @@ const Layer& Display::GetLayer(std::size_t index) const {
|
||||||
return *layers.at(index);
|
return *layers.at(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::KReadableEvent& Display::GetVSyncEvent() {
|
ResultVal<Kernel::KReadableEvent*> Display::GetVSyncEvent() {
|
||||||
return vsync_event->GetReadableEvent();
|
if (got_vsync_event) {
|
||||||
|
return ResultPermissionDenied;
|
||||||
|
}
|
||||||
|
|
||||||
|
got_vsync_event = true;
|
||||||
|
|
||||||
|
return GetVSyncEventUnchecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
Kernel::KReadableEvent* Display::GetVSyncEventUnchecked() {
|
||||||
|
return &vsync_event->GetReadableEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Display::SignalVSyncEvent() {
|
void Display::SignalVSyncEvent() {
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "core/hle/result.h"
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
class KEvent;
|
class KEvent;
|
||||||
|
@ -78,8 +79,16 @@ public:
|
||||||
return layers.size();
|
return layers.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the readable vsync event.
|
/**
|
||||||
Kernel::KReadableEvent& GetVSyncEvent();
|
* Gets the internal vsync event.
|
||||||
|
*
|
||||||
|
* @returns The internal Vsync event if it has not yet been retrieved,
|
||||||
|
* VI::ResultPermissionDenied otherwise.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] ResultVal<Kernel::KReadableEvent*> GetVSyncEvent();
|
||||||
|
|
||||||
|
/// Gets the internal vsync event.
|
||||||
|
Kernel::KReadableEvent* GetVSyncEventUnchecked();
|
||||||
|
|
||||||
/// Signals the internal vsync event.
|
/// Signals the internal vsync event.
|
||||||
void SignalVSyncEvent();
|
void SignalVSyncEvent();
|
||||||
|
@ -123,6 +132,7 @@ private:
|
||||||
|
|
||||||
std::vector<std::unique_ptr<Layer>> layers;
|
std::vector<std::unique_ptr<Layer>> layers;
|
||||||
Kernel::KEvent* vsync_event{};
|
Kernel::KEvent* vsync_event{};
|
||||||
|
bool got_vsync_event{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::VI
|
} // namespace Service::VI
|
||||||
|
|
|
@ -29,16 +29,12 @@
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
#include "core/hle/service/vi/vi.h"
|
#include "core/hle/service/vi/vi.h"
|
||||||
#include "core/hle/service/vi/vi_m.h"
|
#include "core/hle/service/vi/vi_m.h"
|
||||||
|
#include "core/hle/service/vi/vi_results.h"
|
||||||
#include "core/hle/service/vi/vi_s.h"
|
#include "core/hle/service/vi/vi_s.h"
|
||||||
#include "core/hle/service/vi/vi_u.h"
|
#include "core/hle/service/vi/vi_u.h"
|
||||||
|
|
||||||
namespace Service::VI {
|
namespace Service::VI {
|
||||||
|
|
||||||
constexpr Result ERR_OPERATION_FAILED{ErrorModule::VI, 1};
|
|
||||||
constexpr Result ERR_PERMISSION_DENIED{ErrorModule::VI, 5};
|
|
||||||
constexpr Result ERR_UNSUPPORTED{ErrorModule::VI, 6};
|
|
||||||
constexpr Result ERR_NOT_FOUND{ErrorModule::VI, 7};
|
|
||||||
|
|
||||||
struct DisplayInfo {
|
struct DisplayInfo {
|
||||||
/// The name of this particular display.
|
/// The name of this particular display.
|
||||||
char display_name[0x40]{"Default"};
|
char display_name[0x40]{"Default"};
|
||||||
|
@ -349,7 +345,7 @@ private:
|
||||||
if (!layer_id) {
|
if (!layer_id) {
|
||||||
LOG_ERROR(Service_VI, "Layer not found! display=0x{:016X}", display);
|
LOG_ERROR(Service_VI, "Layer not found! display=0x{:016X}", display);
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ERR_NOT_FOUND);
|
rb.Push(ResultNotFound);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,7 +495,7 @@ private:
|
||||||
if (!display_id) {
|
if (!display_id) {
|
||||||
LOG_ERROR(Service_VI, "Display not found! display_name={}", name);
|
LOG_ERROR(Service_VI, "Display not found! display_name={}", name);
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ERR_NOT_FOUND);
|
rb.Push(ResultNotFound);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -555,14 +551,14 @@ private:
|
||||||
|
|
||||||
if (scaling_mode > NintendoScaleMode::PreserveAspectRatio) {
|
if (scaling_mode > NintendoScaleMode::PreserveAspectRatio) {
|
||||||
LOG_ERROR(Service_VI, "Invalid scaling mode provided.");
|
LOG_ERROR(Service_VI, "Invalid scaling mode provided.");
|
||||||
rb.Push(ERR_OPERATION_FAILED);
|
rb.Push(ResultOperationFailed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scaling_mode != NintendoScaleMode::ScaleToWindow &&
|
if (scaling_mode != NintendoScaleMode::ScaleToWindow &&
|
||||||
scaling_mode != NintendoScaleMode::PreserveAspectRatio) {
|
scaling_mode != NintendoScaleMode::PreserveAspectRatio) {
|
||||||
LOG_ERROR(Service_VI, "Unsupported scaling mode supplied.");
|
LOG_ERROR(Service_VI, "Unsupported scaling mode supplied.");
|
||||||
rb.Push(ERR_UNSUPPORTED);
|
rb.Push(ResultNotSupported);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,7 +591,7 @@ private:
|
||||||
if (!display_id) {
|
if (!display_id) {
|
||||||
LOG_ERROR(Service_VI, "Layer not found! layer_id={}", layer_id);
|
LOG_ERROR(Service_VI, "Layer not found! layer_id={}", layer_id);
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ERR_NOT_FOUND);
|
rb.Push(ResultNotFound);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -603,7 +599,7 @@ private:
|
||||||
if (!buffer_queue_id) {
|
if (!buffer_queue_id) {
|
||||||
LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", *display_id);
|
LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", *display_id);
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ERR_NOT_FOUND);
|
rb.Push(ResultNotFound);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,7 +637,7 @@ private:
|
||||||
if (!layer_id) {
|
if (!layer_id) {
|
||||||
LOG_ERROR(Service_VI, "Layer not found! display_id={}", display_id);
|
LOG_ERROR(Service_VI, "Layer not found! display_id={}", display_id);
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ERR_NOT_FOUND);
|
rb.Push(ResultNotFound);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -649,7 +645,7 @@ private:
|
||||||
if (!buffer_queue_id) {
|
if (!buffer_queue_id) {
|
||||||
LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", display_id);
|
LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", display_id);
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ERR_NOT_FOUND);
|
rb.Push(ResultNotFound);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,19 +672,23 @@ private:
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const u64 display_id = rp.Pop<u64>();
|
const u64 display_id = rp.Pop<u64>();
|
||||||
|
|
||||||
LOG_WARNING(Service_VI, "(STUBBED) called. display_id=0x{:016X}", display_id);
|
LOG_DEBUG(Service_VI, "called. display_id={}", display_id);
|
||||||
|
|
||||||
const auto vsync_event = nv_flinger.FindVsyncEvent(display_id);
|
const auto vsync_event = nv_flinger.FindVsyncEvent(display_id);
|
||||||
if (!vsync_event) {
|
if (vsync_event.Failed()) {
|
||||||
|
const auto result = vsync_event.Code();
|
||||||
|
if (result == ResultNotFound) {
|
||||||
LOG_ERROR(Service_VI, "Vsync event was not found for display_id={}", display_id);
|
LOG_ERROR(Service_VI, "Vsync event was not found for display_id={}", display_id);
|
||||||
|
}
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ERR_NOT_FOUND);
|
rb.Push(result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.PushCopyObjects(vsync_event);
|
rb.PushCopyObjects(*vsync_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConvertScalingMode(Kernel::HLERequestContext& ctx) {
|
void ConvertScalingMode(Kernel::HLERequestContext& ctx) {
|
||||||
|
@ -765,7 +765,7 @@ private:
|
||||||
return ConvertedScaleMode::PreserveAspectRatio;
|
return ConvertedScaleMode::PreserveAspectRatio;
|
||||||
default:
|
default:
|
||||||
LOG_ERROR(Service_VI, "Invalid scaling mode specified, mode={}", mode);
|
LOG_ERROR(Service_VI, "Invalid scaling mode specified, mode={}", mode);
|
||||||
return ERR_OPERATION_FAILED;
|
return ResultOperationFailed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -795,7 +795,7 @@ void detail::GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, Core::System&
|
||||||
if (!IsValidServiceAccess(permission, policy)) {
|
if (!IsValidServiceAccess(permission, policy)) {
|
||||||
LOG_ERROR(Service_VI, "Permission denied for policy {}", policy);
|
LOG_ERROR(Service_VI, "Permission denied for policy {}", policy);
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ERR_PERMISSION_DENIED);
|
rb.Push(ResultPermissionDenied);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
13
src/core/hle/service/vi/vi_results.h
Executable file
13
src/core/hle/service/vi/vi_results.h
Executable file
|
@ -0,0 +1,13 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "core/hle/result.h"
|
||||||
|
|
||||||
|
namespace Service::VI {
|
||||||
|
|
||||||
|
constexpr Result ResultOperationFailed{ErrorModule::VI, 1};
|
||||||
|
constexpr Result ResultPermissionDenied{ErrorModule::VI, 5};
|
||||||
|
constexpr Result ResultNotSupported{ErrorModule::VI, 6};
|
||||||
|
constexpr Result ResultNotFound{ErrorModule::VI, 7};
|
||||||
|
|
||||||
|
} // namespace Service::VI
|
|
@ -244,6 +244,10 @@ static std::unique_ptr<AppLoader> GetFileLoader(Core::System& system, FileSys::V
|
||||||
|
|
||||||
std::unique_ptr<AppLoader> GetLoader(Core::System& system, FileSys::VirtualFile file,
|
std::unique_ptr<AppLoader> GetLoader(Core::System& system, FileSys::VirtualFile file,
|
||||||
u64 program_id, std::size_t program_index) {
|
u64 program_id, std::size_t program_index) {
|
||||||
|
if (!file) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
FileType type = IdentifyFile(file);
|
FileType type = IdentifyFile(file);
|
||||||
const FileType filename_type = GuessFromFilename(file->GetName());
|
const FileType filename_type = GuessFromFilename(file->GetName());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue