video_core: gpu: Refactor out synchronous/asynchronous GPU implementations.
- We must always use a GPU thread now, even with synchronous GPU.master
parent
5d4715cc6a
commit
14c825bd1c
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright 2020 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Tegra {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Struct describing framebuffer configuration
|
||||||
|
*/
|
||||||
|
struct FramebufferConfig {
|
||||||
|
enum class PixelFormat : u32 {
|
||||||
|
A8B8G8R8_UNORM = 1,
|
||||||
|
RGB565_UNORM = 4,
|
||||||
|
B8G8R8A8_UNORM = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
VAddr address{};
|
||||||
|
u32 offset{};
|
||||||
|
u32 width{};
|
||||||
|
u32 height{};
|
||||||
|
u32 stride{};
|
||||||
|
PixelFormat pixel_format{};
|
||||||
|
|
||||||
|
using TransformFlags = Service::NVFlinger::BufferQueue::BufferTransformFlags;
|
||||||
|
TransformFlags transform_flags{};
|
||||||
|
Common::Rectangle<int> crop_rect;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Tegra
|
@ -1,86 +0,0 @@
|
|||||||
// Copyright 2019 yuzu Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include "core/core.h"
|
|
||||||
#include "core/hardware_interrupt_manager.h"
|
|
||||||
#include "video_core/gpu_asynch.h"
|
|
||||||
#include "video_core/gpu_thread.h"
|
|
||||||
#include "video_core/renderer_base.h"
|
|
||||||
|
|
||||||
namespace VideoCommon {
|
|
||||||
|
|
||||||
GPUAsynch::GPUAsynch(Core::System& system_, bool use_nvdec_)
|
|
||||||
: GPU{system_, true, use_nvdec_}, gpu_thread{system_} {}
|
|
||||||
|
|
||||||
GPUAsynch::~GPUAsynch() = default;
|
|
||||||
|
|
||||||
void GPUAsynch::Start() {
|
|
||||||
gpu_thread.StartThread(*renderer, renderer->Context(), *dma_pusher, *cdma_pusher);
|
|
||||||
cpu_context = renderer->GetRenderWindow().CreateSharedContext();
|
|
||||||
cpu_context->MakeCurrent();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUAsynch::ObtainContext() {
|
|
||||||
cpu_context->MakeCurrent();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUAsynch::ReleaseContext() {
|
|
||||||
cpu_context->DoneCurrent();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUAsynch::PushGPUEntries(Tegra::CommandList&& entries) {
|
|
||||||
gpu_thread.SubmitList(std::move(entries));
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUAsynch::PushCommandBuffer(Tegra::ChCommandHeaderList& entries) {
|
|
||||||
if (!use_nvdec) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// This condition fires when a video stream ends, clear all intermediary data
|
|
||||||
if (entries[0].raw == 0xDEADB33F) {
|
|
||||||
cdma_pusher.reset();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!cdma_pusher) {
|
|
||||||
cdma_pusher = std::make_unique<Tegra::CDmaPusher>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// SubmitCommandBuffer would make the nvdec operations async, this is not currently working
|
|
||||||
// TODO(ameerj): RE proper async nvdec operation
|
|
||||||
// gpu_thread.SubmitCommandBuffer(std::move(entries));
|
|
||||||
|
|
||||||
cdma_pusher->Push(std::move(entries));
|
|
||||||
cdma_pusher->DispatchCalls();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUAsynch::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
|
|
||||||
gpu_thread.SwapBuffers(framebuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUAsynch::FlushRegion(VAddr addr, u64 size) {
|
|
||||||
gpu_thread.FlushRegion(addr, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUAsynch::InvalidateRegion(VAddr addr, u64 size) {
|
|
||||||
gpu_thread.InvalidateRegion(addr, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUAsynch::FlushAndInvalidateRegion(VAddr addr, u64 size) {
|
|
||||||
gpu_thread.FlushAndInvalidateRegion(addr, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUAsynch::TriggerCpuInterrupt(const u32 syncpoint_id, const u32 value) const {
|
|
||||||
auto& interrupt_manager = system.InterruptManager();
|
|
||||||
interrupt_manager.GPUInterruptSyncpt(syncpoint_id, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUAsynch::WaitIdle() const {
|
|
||||||
gpu_thread.WaitIdle();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUAsynch::OnCommandListEnd() {
|
|
||||||
gpu_thread.OnCommandListEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace VideoCommon
|
|
@ -1,47 +0,0 @@
|
|||||||
// Copyright 2019 yuzu Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "video_core/gpu.h"
|
|
||||||
#include "video_core/gpu_thread.h"
|
|
||||||
|
|
||||||
namespace Core::Frontend {
|
|
||||||
class GraphicsContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace VideoCore {
|
|
||||||
class RendererBase;
|
|
||||||
} // namespace VideoCore
|
|
||||||
|
|
||||||
namespace VideoCommon {
|
|
||||||
|
|
||||||
/// Implementation of GPU interface that runs the GPU asynchronously
|
|
||||||
class GPUAsynch final : public Tegra::GPU {
|
|
||||||
public:
|
|
||||||
explicit GPUAsynch(Core::System& system_, bool use_nvdec_);
|
|
||||||
~GPUAsynch() override;
|
|
||||||
|
|
||||||
void Start() override;
|
|
||||||
void ObtainContext() override;
|
|
||||||
void ReleaseContext() override;
|
|
||||||
void PushGPUEntries(Tegra::CommandList&& entries) override;
|
|
||||||
void PushCommandBuffer(Tegra::ChCommandHeaderList& entries) override;
|
|
||||||
void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override;
|
|
||||||
void FlushRegion(VAddr addr, u64 size) override;
|
|
||||||
void InvalidateRegion(VAddr addr, u64 size) override;
|
|
||||||
void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
|
|
||||||
void WaitIdle() const override;
|
|
||||||
|
|
||||||
void OnCommandListEnd() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void TriggerCpuInterrupt(u32 syncpoint_id, u32 value) const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
GPUThread::ThreadManager gpu_thread;
|
|
||||||
std::unique_ptr<Core::Frontend::GraphicsContext> cpu_context;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace VideoCommon
|
|
@ -1,61 +0,0 @@
|
|||||||
// Copyright 2019 yuzu Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include "video_core/gpu_synch.h"
|
|
||||||
#include "video_core/renderer_base.h"
|
|
||||||
|
|
||||||
namespace VideoCommon {
|
|
||||||
|
|
||||||
GPUSynch::GPUSynch(Core::System& system_, bool use_nvdec_) : GPU{system_, false, use_nvdec_} {}
|
|
||||||
|
|
||||||
GPUSynch::~GPUSynch() = default;
|
|
||||||
|
|
||||||
void GPUSynch::Start() {}
|
|
||||||
|
|
||||||
void GPUSynch::ObtainContext() {
|
|
||||||
renderer->Context().MakeCurrent();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUSynch::ReleaseContext() {
|
|
||||||
renderer->Context().DoneCurrent();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUSynch::PushGPUEntries(Tegra::CommandList&& entries) {
|
|
||||||
dma_pusher->Push(std::move(entries));
|
|
||||||
dma_pusher->DispatchCalls();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUSynch::PushCommandBuffer(Tegra::ChCommandHeaderList& entries) {
|
|
||||||
if (!use_nvdec) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// This condition fires when a video stream ends, clears all intermediary data
|
|
||||||
if (entries[0].raw == 0xDEADB33F) {
|
|
||||||
cdma_pusher.reset();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!cdma_pusher) {
|
|
||||||
cdma_pusher = std::make_unique<Tegra::CDmaPusher>(*this);
|
|
||||||
}
|
|
||||||
cdma_pusher->Push(std::move(entries));
|
|
||||||
cdma_pusher->DispatchCalls();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUSynch::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
|
|
||||||
renderer->SwapBuffers(framebuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUSynch::FlushRegion(VAddr addr, u64 size) {
|
|
||||||
renderer->Rasterizer().FlushRegion(addr, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUSynch::InvalidateRegion(VAddr addr, u64 size) {
|
|
||||||
renderer->Rasterizer().InvalidateRegion(addr, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPUSynch::FlushAndInvalidateRegion(VAddr addr, u64 size) {
|
|
||||||
renderer->Rasterizer().FlushAndInvalidateRegion(addr, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace VideoCommon
|
|
@ -1,41 +0,0 @@
|
|||||||
// Copyright 2019 yuzu Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "video_core/gpu.h"
|
|
||||||
|
|
||||||
namespace Core::Frontend {
|
|
||||||
class GraphicsContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace VideoCore {
|
|
||||||
class RendererBase;
|
|
||||||
} // namespace VideoCore
|
|
||||||
|
|
||||||
namespace VideoCommon {
|
|
||||||
|
|
||||||
/// Implementation of GPU interface that runs the GPU synchronously
|
|
||||||
class GPUSynch final : public Tegra::GPU {
|
|
||||||
public:
|
|
||||||
explicit GPUSynch(Core::System& system_, bool use_nvdec_);
|
|
||||||
~GPUSynch() override;
|
|
||||||
|
|
||||||
void Start() override;
|
|
||||||
void ObtainContext() override;
|
|
||||||
void ReleaseContext() override;
|
|
||||||
void PushGPUEntries(Tegra::CommandList&& entries) override;
|
|
||||||
void PushCommandBuffer(Tegra::ChCommandHeaderList& entries) override;
|
|
||||||
void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override;
|
|
||||||
void FlushRegion(VAddr addr, u64 size) override;
|
|
||||||
void InvalidateRegion(VAddr addr, u64 size) override;
|
|
||||||
void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
|
|
||||||
void WaitIdle() const override {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void TriggerCpuInterrupt([[maybe_unused]] u32 syncpoint_id,
|
|
||||||
[[maybe_unused]] u32 value) const override {}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace VideoCommon
|
|
Loading…
Reference in New Issue