early-access version 2041
This commit is contained in:
@@ -491,7 +491,7 @@ public:
|
||||
|
||||
class EnsureTokenIdCacheAsyncInterface final : public IAsyncContext {
|
||||
public:
|
||||
explicit EnsureTokenIdCacheAsyncInterface(Core::System& system_) : IAsyncContext(system_) {
|
||||
explicit EnsureTokenIdCacheAsyncInterface(Core::System& system_) : IAsyncContext{system_} {
|
||||
MarkComplete();
|
||||
}
|
||||
~EnsureTokenIdCacheAsyncInterface() = default;
|
||||
@@ -504,13 +504,13 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
bool IsComplete() override {
|
||||
bool IsComplete() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Cancel() override {}
|
||||
|
||||
ResultCode GetResult() override {
|
||||
ResultCode GetResult() const override {
|
||||
return ResultSuccess;
|
||||
}
|
||||
};
|
||||
@@ -518,7 +518,9 @@ protected:
|
||||
class IManagerForApplication final : public ServiceFramework<IManagerForApplication> {
|
||||
public:
|
||||
explicit IManagerForApplication(Core::System& system_, Common::UUID user_id_)
|
||||
: ServiceFramework{system_, "IManagerForApplication"}, user_id{user_id_}, system(system_) {
|
||||
: ServiceFramework{system_, "IManagerForApplication"},
|
||||
ensure_token_id{std::make_shared<EnsureTokenIdCacheAsyncInterface>(system)},
|
||||
user_id{user_id_} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IManagerForApplication::CheckAvailability, "CheckAvailability"},
|
||||
@@ -533,8 +535,6 @@ public:
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
|
||||
ensure_token_id = std::make_shared<EnsureTokenIdCacheAsyncInterface>(system);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -591,7 +591,6 @@ private:
|
||||
|
||||
std::shared_ptr<EnsureTokenIdCacheAsyncInterface> ensure_token_id{};
|
||||
Common::UUID user_id{Common::INVALID_UUID};
|
||||
Core::System& system;
|
||||
};
|
||||
|
||||
// 6.0.0+
|
||||
|
@@ -14,12 +14,12 @@ IAsyncContext::IAsyncContext(Core::System& system_)
|
||||
compeletion_event.Initialize("IAsyncContext:CompletionEvent");
|
||||
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IAsyncContext::GetSystemEvent, "GetSystemEvent"},
|
||||
{1, &IAsyncContext::Cancel, "Cancel"},
|
||||
{2, &IAsyncContext::HasDone, "HasDone"},
|
||||
{3, &IAsyncContext::GetResult, "GetResult"},
|
||||
};
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IAsyncContext::GetSystemEvent, "GetSystemEvent"},
|
||||
{1, &IAsyncContext::Cancel, "Cancel"},
|
||||
{2, &IAsyncContext::HasDone, "HasDone"},
|
||||
{3, &IAsyncContext::GetResult, "GetResult"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
RegisterHandlers(functions);
|
||||
@@ -46,11 +46,11 @@ void IAsyncContext::Cancel(Kernel::HLERequestContext& ctx) {
|
||||
void IAsyncContext::HasDone(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_ACC, "called");
|
||||
|
||||
is_complete = IsComplete();
|
||||
is_complete.store(IsComplete());
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push(is_complete);
|
||||
rb.Push(is_complete.load());
|
||||
}
|
||||
|
||||
void IAsyncContext::GetResult(Kernel::HLERequestContext& ctx) {
|
||||
@@ -61,7 +61,7 @@ void IAsyncContext::GetResult(Kernel::HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
void IAsyncContext::MarkComplete() {
|
||||
is_complete = true;
|
||||
is_complete.store(true);
|
||||
compeletion_event.GetWritableEvent().Signal();
|
||||
}
|
||||
|
||||
|
@@ -4,6 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
@@ -23,13 +24,13 @@ public:
|
||||
void GetResult(Kernel::HLERequestContext& ctx);
|
||||
|
||||
protected:
|
||||
virtual bool IsComplete() = 0;
|
||||
virtual bool IsComplete() const = 0;
|
||||
virtual void Cancel() = 0;
|
||||
virtual ResultCode GetResult() = 0;
|
||||
virtual ResultCode GetResult() const = 0;
|
||||
|
||||
void MarkComplete();
|
||||
|
||||
bool is_complete{false};
|
||||
std::atomic<bool> is_complete{false};
|
||||
Kernel::KEvent compeletion_event;
|
||||
};
|
||||
|
||||
|
@@ -98,7 +98,7 @@ ResultCode VfsDirectoryServiceWrapper::DeleteFile(const std::string& path_) cons
|
||||
ResultCode VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path_) const {
|
||||
std::string path(Common::FS::SanitizePath(path_));
|
||||
const auto components = Common::FS::SplitPathComponents(path);
|
||||
std::string relative_path = "";
|
||||
std::string relative_path;
|
||||
for (const auto& component : components) {
|
||||
// Skip empty path components
|
||||
if (component.empty()) {
|
||||
|
@@ -5,8 +5,10 @@
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
|
||||
#include "core/hle/service/nvdrv/devices/nvmap.h"
|
||||
#include "core/perf_stats.h"
|
||||
#include "video_core/gpu.h"
|
||||
#include "video_core/renderer_base.h"
|
||||
|
||||
@@ -39,7 +41,7 @@ void nvdisp_disp0::OnClose(DeviceFD fd) {}
|
||||
|
||||
void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height,
|
||||
u32 stride, NVFlinger::BufferQueue::BufferTransformFlags transform,
|
||||
const Common::Rectangle<int>& crop_rect, const MultiFence& fences) {
|
||||
const Common::Rectangle<int>& crop_rect) {
|
||||
VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle);
|
||||
LOG_TRACE(Service,
|
||||
"Drawing from address {:X} offset {:08X} Width {} Height {} Stride {} Format {}",
|
||||
@@ -50,7 +52,10 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3
|
||||
addr, offset, width, height, stride, static_cast<PixelFormat>(format),
|
||||
transform, crop_rect};
|
||||
|
||||
system.GPU().QueueFrame(&framebuffer, fences);
|
||||
system.GetPerfStats().EndSystemFrame();
|
||||
system.GPU().SwapBuffers(&framebuffer);
|
||||
system.SpeedLimiter().DoSpeedLimiting(system.CoreTiming().GetGlobalTimeUs());
|
||||
system.GetPerfStats().BeginSystemFrame();
|
||||
}
|
||||
|
||||
} // namespace Service::Nvidia::Devices
|
||||
|
@@ -33,7 +33,7 @@ public:
|
||||
/// Performs a screen flip, drawing the buffer pointed to by the handle.
|
||||
void flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u32 height, u32 stride,
|
||||
NVFlinger::BufferQueue::BufferTransformFlags transform,
|
||||
const Common::Rectangle<int>& crop_rect, const MultiFence& fence);
|
||||
const Common::Rectangle<int>& crop_rect);
|
||||
|
||||
private:
|
||||
std::shared_ptr<nvmap> nvmap_dev;
|
||||
|
@@ -91,10 +91,6 @@ const IGBPBuffer& BufferQueue::RequestBuffer(u32 slot) const {
|
||||
return buffers[slot].igbp_buffer;
|
||||
}
|
||||
|
||||
const BufferQueue::Buffer& BufferQueue::AccessBuffer(u32 slot) const {
|
||||
return buffers[slot];
|
||||
}
|
||||
|
||||
void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform,
|
||||
const Common::Rectangle<int>& crop_rect, u32 swap_interval,
|
||||
Service::Nvidia::MultiFence& multi_fence) {
|
||||
|
@@ -112,7 +112,6 @@ public:
|
||||
void Connect();
|
||||
void Disconnect();
|
||||
u32 Query(QueryType type);
|
||||
const Buffer& AccessBuffer(u32 slot) const;
|
||||
|
||||
u32 GetId() const {
|
||||
return id;
|
||||
|
@@ -275,6 +275,8 @@ void NVFlinger::Compose() {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& igbp_buffer = buffer->get().igbp_buffer;
|
||||
|
||||
if (!system.IsPoweredOn()) {
|
||||
return; // We are likely shutting down
|
||||
}
|
||||
@@ -288,31 +290,23 @@ void NVFlinger::Compose() {
|
||||
}
|
||||
guard->lock();
|
||||
|
||||
system.GetPerfStats().EndSystemFrame();
|
||||
MicroProfileFlip();
|
||||
system.SpeedLimiter().DoSpeedLimiting(system.CoreTiming().GetGlobalTimeUs());
|
||||
system.GetPerfStats().BeginSystemFrame();
|
||||
|
||||
// Now send the buffer to the GPU for drawing.
|
||||
// TODO(Subv): Support more than just disp0. The display device selection is probably based
|
||||
// on which display we're drawing (Default, Internal, External, etc)
|
||||
auto nvdisp = nvdrv->GetDevice<Nvidia::Devices::nvdisp_disp0>("/dev/nvdisp_disp0");
|
||||
ASSERT(nvdisp);
|
||||
|
||||
nvdisp->flip(igbp_buffer.gpu_buffer_id, igbp_buffer.offset, igbp_buffer.format,
|
||||
igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride,
|
||||
buffer->get().transform, buffer->get().crop_rect);
|
||||
|
||||
swap_interval = buffer->get().swap_interval;
|
||||
buffer_queue.ReleaseBuffer(buffer->get().slot);
|
||||
}
|
||||
}
|
||||
|
||||
void NVFlinger::PrequeueFrame(u32 buffer_queue_id, u32 slot) {
|
||||
auto& buffer_queue = *FindBufferQueue(buffer_queue_id);
|
||||
const auto& buffer = buffer_queue.AccessBuffer(slot);
|
||||
const auto& igbp_buffer = buffer.igbp_buffer;
|
||||
|
||||
// Now send the buffer to the GPU for drawing.
|
||||
// TODO(Subv): Support more than just disp0. The display device selection is probably based
|
||||
// on which display we're drawing (Default, Internal, External, etc)
|
||||
auto nvdisp = nvdrv->GetDevice<Nvidia::Devices::nvdisp_disp0>("/dev/nvdisp_disp0");
|
||||
ASSERT(nvdisp);
|
||||
nvdisp->flip(igbp_buffer.gpu_buffer_id, igbp_buffer.offset, igbp_buffer.format,
|
||||
igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride, buffer.transform,
|
||||
buffer.crop_rect, buffer.multi_fence);
|
||||
}
|
||||
|
||||
s64 NVFlinger::GetNextTicks() const {
|
||||
static constexpr s64 max_hertz = 120LL;
|
||||
|
||||
|
@@ -78,8 +78,6 @@ public:
|
||||
/// Obtains a buffer queue identified by the ID.
|
||||
[[nodiscard]] BufferQueue* FindBufferQueue(u32 id);
|
||||
|
||||
void PrequeueFrame(u32 buffer_queue_id, u32 slot);
|
||||
|
||||
/// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when
|
||||
/// finished.
|
||||
void Compose();
|
||||
|
@@ -592,7 +592,6 @@ private:
|
||||
buffer_queue.QueueBuffer(request.data.slot, request.data.transform,
|
||||
request.data.GetCropRect(), request.data.swap_interval,
|
||||
request.data.multi_fence);
|
||||
nv_flinger.PrequeueFrame(id, request.data.slot);
|
||||
|
||||
IGBPQueueBufferResponseParcel response{1280, 720};
|
||||
ctx.WriteBuffer(response.Serialize());
|
||||
|
Reference in New Issue
Block a user