early-access version 1950

This commit is contained in:
pineappleEA
2021-07-31 19:18:23 +02:00
parent dff640ccbc
commit c8066f9a11
13 changed files with 229 additions and 52 deletions

View File

@@ -5,10 +5,8 @@
#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"
@@ -41,7 +39,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 Common::Rectangle<int>& crop_rect, const MultiFence& fences) {
VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle);
LOG_TRACE(Service,
"Drawing from address {:X} offset {:08X} Width {} Height {} Stride {} Format {}",
@@ -52,10 +50,7 @@ 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.GetPerfStats().EndSystemFrame();
system.GPU().SwapBuffers(&framebuffer);
system.SpeedLimiter().DoSpeedLimiting(system.CoreTiming().GetGlobalTimeUs());
system.GetPerfStats().BeginSystemFrame();
system.GPU().QueueFrame(&framebuffer, fences);
}
} // namespace Service::Nvidia::Devices

View File

@@ -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 Common::Rectangle<int>& crop_rect, const MultiFence& fence);
private:
std::shared_ptr<nvmap> nvmap_dev;

View File

@@ -88,6 +88,10 @@ 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) {

View File

@@ -107,6 +107,7 @@ public:
void Connect();
void Disconnect();
u32 Query(QueryType type);
const Buffer& AccessBuffer(u32 slot) const;
u32 GetId() const {
return id;

View File

@@ -274,8 +274,6 @@ void NVFlinger::Compose() {
continue;
}
const auto& igbp_buffer = buffer->get().igbp_buffer;
if (!system.IsPoweredOn()) {
return; // We are likely shutting down
}
@@ -289,23 +287,31 @@ void NVFlinger::Compose() {
}
guard->lock();
system.GetPerfStats().EndSystemFrame();
MicroProfileFlip();
// 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);
system.SpeedLimiter().DoSpeedLimiting(system.CoreTiming().GetGlobalTimeUs());
system.GetPerfStats().BeginSystemFrame();
swap_interval = buffer->get().swap_interval;
buffer_queue.ReleaseBuffer(buffer->get().slot);
}
}
void NVFlinger::PrequeeFrame(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;

View File

@@ -77,6 +77,8 @@ public:
/// Obtains a buffer queue identified by the ID.
[[nodiscard]] BufferQueue* FindBufferQueue(u32 id);
void PrequeeFrame(u32 buffer_queue_id, u32 slot);
/// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when
/// finished.
void Compose();

View File

@@ -592,6 +592,7 @@ private:
buffer_queue.QueueBuffer(request.data.slot, request.data.transform,
request.data.GetCropRect(), request.data.swap_interval,
request.data.multi_fence);
nv_flinger.PrequeeFrame(id, request.data.slot);
IGBPQueueBufferResponseParcel response{1280, 720};
ctx.WriteBuffer(response.Serialize());