video_core: add null backend

This commit is contained in:
Liam 2022-11-27 20:37:37 -05:00
parent 6b64557ad6
commit 89dd7dc180
20 changed files with 383 additions and 28 deletions

View file

@ -91,6 +91,10 @@ add_library(video_core STATIC
rasterizer_interface.h
renderer_base.cpp
renderer_base.h
renderer_null/null_rasterizer.cpp
renderer_null/null_rasterizer.h
renderer_null/renderer_null.cpp
renderer_null/renderer_null.h
renderer_opengl/gl_buffer_cache.cpp
renderer_opengl/gl_buffer_cache.h
renderer_opengl/gl_compute_pipeline.cpp

View file

@ -0,0 +1,90 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "video_core/host1x/host1x.h"
#include "video_core/memory_manager.h"
#include "video_core/renderer_null/null_rasterizer.h"
namespace Null {
AccelerateDMA::AccelerateDMA() = default;
bool AccelerateDMA::BufferCopy(GPUVAddr start_address, GPUVAddr end_address, u64 amount) {
return true;
}
bool AccelerateDMA::BufferClear(GPUVAddr src_address, u64 amount, u32 value) {
return true;
}
RasterizerNull::RasterizerNull(Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu)
: RasterizerAccelerated(cpu_memory_), m_gpu{gpu} {}
RasterizerNull::~RasterizerNull() = default;
void RasterizerNull::Draw(bool is_indexed, u32 instance_count) {}
void RasterizerNull::Clear(u32 layer_count) {}
void RasterizerNull::DispatchCompute() {}
void RasterizerNull::ResetCounter(VideoCore::QueryType type) {}
void RasterizerNull::Query(GPUVAddr gpu_addr, VideoCore::QueryType type,
std::optional<u64> timestamp) {
if (!gpu_memory) {
return;
}
gpu_memory->Write(gpu_addr, u64{0});
if (timestamp) {
gpu_memory->Write(gpu_addr + 8, *timestamp);
}
}
void RasterizerNull::BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr gpu_addr,
u32 size) {}
void RasterizerNull::DisableGraphicsUniformBuffer(size_t stage, u32 index) {}
void RasterizerNull::FlushAll() {}
void RasterizerNull::FlushRegion(VAddr addr, u64 size) {}
bool RasterizerNull::MustFlushRegion(VAddr addr, u64 size) {
return false;
}
void RasterizerNull::InvalidateRegion(VAddr addr, u64 size) {}
void RasterizerNull::OnCPUWrite(VAddr addr, u64 size) {}
void RasterizerNull::InvalidateGPUCache() {}
void RasterizerNull::UnmapMemory(VAddr addr, u64 size) {}
void RasterizerNull::ModifyGPUMemory(size_t as_id, GPUVAddr addr, u64 size) {}
void RasterizerNull::SignalFence(std::function<void()>&& func) {
func();
}
void RasterizerNull::SyncOperation(std::function<void()>&& func) {
func();
}
void RasterizerNull::SignalSyncPoint(u32 value) {
auto& syncpoint_manager = m_gpu.Host1x().GetSyncpointManager();
syncpoint_manager.IncrementGuest(value);
syncpoint_manager.IncrementHost(value);
}
void RasterizerNull::SignalReference() {}
void RasterizerNull::ReleaseFences() {}
void RasterizerNull::FlushAndInvalidateRegion(VAddr addr, u64 size) {}
void RasterizerNull::WaitForIdle() {}
void RasterizerNull::FragmentBarrier() {}
void RasterizerNull::TiledCacheBarrier() {}
void RasterizerNull::FlushCommands() {}
void RasterizerNull::TickFrame() {}
Tegra::Engines::AccelerateDMAInterface& RasterizerNull::AccessAccelerateDMA() {
return m_accelerate_dma;
}
bool RasterizerNull::AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Surface& src,
const Tegra::Engines::Fermi2D::Surface& dst,
const Tegra::Engines::Fermi2D::Config& copy_config) {
return true;
}
void RasterizerNull::AccelerateInlineToMemory(GPUVAddr address, size_t copy_size,
std::span<const u8> memory) {}
bool RasterizerNull::AccelerateDisplay(const Tegra::FramebufferConfig& config,
VAddr framebuffer_addr, u32 pixel_stride) {
return true;
}
void RasterizerNull::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
const VideoCore::DiskResourceLoadCallback& callback) {}
void RasterizerNull::InitializeChannel(Tegra::Control::ChannelState& channel) {}
void RasterizerNull::BindChannel(Tegra::Control::ChannelState& channel) {}
void RasterizerNull::ReleaseChannel(s32 channel_id) {}
} // namespace Null

View file

@ -0,0 +1,78 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/common_types.h"
#include "video_core/control/channel_state_cache.h"
#include "video_core/engines/maxwell_dma.h"
#include "video_core/rasterizer_accelerated.h"
#include "video_core/rasterizer_interface.h"
namespace Core {
class System;
}
namespace Null {
class RasterizerNull;
class AccelerateDMA : public Tegra::Engines::AccelerateDMAInterface {
public:
explicit AccelerateDMA();
bool BufferCopy(GPUVAddr start_address, GPUVAddr end_address, u64 amount) override;
bool BufferClear(GPUVAddr src_address, u64 amount, u32 value) override;
};
class RasterizerNull final : public VideoCore::RasterizerAccelerated,
protected VideoCommon::ChannelSetupCaches<VideoCommon::ChannelInfo> {
public:
explicit RasterizerNull(Core::Memory::Memory& cpu_memory, Tegra::GPU& gpu);
~RasterizerNull() override;
void Draw(bool is_indexed, u32 instance_count) override;
void Clear(u32 layer_count) override;
void DispatchCompute() override;
void ResetCounter(VideoCore::QueryType type) override;
void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) override;
void BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr gpu_addr, u32 size) override;
void DisableGraphicsUniformBuffer(size_t stage, u32 index) override;
void FlushAll() override;
void FlushRegion(VAddr addr, u64 size) override;
bool MustFlushRegion(VAddr addr, u64 size) override;
void InvalidateRegion(VAddr addr, u64 size) override;
void OnCPUWrite(VAddr addr, u64 size) override;
void InvalidateGPUCache() override;
void UnmapMemory(VAddr addr, u64 size) override;
void ModifyGPUMemory(size_t as_id, GPUVAddr addr, u64 size) override;
void SignalFence(std::function<void()>&& func) override;
void SyncOperation(std::function<void()>&& func) override;
void SignalSyncPoint(u32 value) override;
void SignalReference() override;
void ReleaseFences() override;
void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
void WaitForIdle() override;
void FragmentBarrier() override;
void TiledCacheBarrier() override;
void FlushCommands() override;
void TickFrame() override;
bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Surface& src,
const Tegra::Engines::Fermi2D::Surface& dst,
const Tegra::Engines::Fermi2D::Config& copy_config) override;
Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() override;
void AccelerateInlineToMemory(GPUVAddr address, size_t copy_size,
std::span<const u8> memory) override;
bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
u32 pixel_stride) override;
void LoadDiskResources(u64 title_id, std::stop_token stop_loading,
const VideoCore::DiskResourceLoadCallback& callback) override;
void InitializeChannel(Tegra::Control::ChannelState& channel) override;
void BindChannel(Tegra::Control::ChannelState& channel) override;
void ReleaseChannel(s32 channel_id) override;
private:
Tegra::GPU& m_gpu;
AccelerateDMA m_accelerate_dma;
};
} // namespace Null

View file

@ -0,0 +1,24 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "video_core/renderer_null/renderer_null.h"
namespace Null {
RendererNull::RendererNull(Core::Frontend::EmuWindow& emu_window, Core::Memory::Memory& cpu_memory,
Tegra::GPU& gpu,
std::unique_ptr<Core::Frontend::GraphicsContext> context_)
: RendererBase(emu_window, std::move(context_)), m_gpu(gpu), m_rasterizer(cpu_memory, gpu) {}
RendererNull::~RendererNull() = default;
void RendererNull::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
if (!framebuffer) {
return;
}
m_gpu.RendererFrameEndNotify();
render_window.OnFrameDisplayed();
}
} // namespace Null

View file

@ -0,0 +1,36 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <memory>
#include <string>
#include "video_core/renderer_base.h"
#include "video_core/renderer_null/null_rasterizer.h"
namespace Null {
class RendererNull final : public VideoCore::RendererBase {
public:
explicit RendererNull(Core::Frontend::EmuWindow& emu_window, Core::Memory::Memory& cpu_memory,
Tegra::GPU& gpu,
std::unique_ptr<Core::Frontend::GraphicsContext> context);
~RendererNull() override;
void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override;
VideoCore::RasterizerInterface* ReadRasterizer() override {
return &m_rasterizer;
}
[[nodiscard]] std::string GetDeviceVendor() const override {
return "NULL";
}
private:
Tegra::GPU& m_gpu;
RasterizerNull m_rasterizer;
};
} // namespace Null

View file

@ -7,6 +7,7 @@
#include "common/settings.h"
#include "core/core.h"
#include "video_core/renderer_base.h"
#include "video_core/renderer_null/renderer_null.h"
#include "video_core/renderer_opengl/renderer_opengl.h"
#include "video_core/renderer_vulkan/renderer_vulkan.h"
#include "video_core/video_core.h"
@ -26,6 +27,9 @@ std::unique_ptr<VideoCore::RendererBase> CreateRenderer(
case Settings::RendererBackend::Vulkan:
return std::make_unique<Vulkan::RendererVulkan>(telemetry_session, emu_window, cpu_memory,
gpu, std::move(context));
case Settings::RendererBackend::Null:
return std::make_unique<Null::RendererNull>(emu_window, cpu_memory, gpu,
std::move(context));
default:
return nullptr;
}