video_core: Eliminate the g_renderer global variable
We move the initialization of the renderer to the core class, while keeping the creation of it and any other specifics in video_core. This way we can ensure that the renderer is initialized and doesn't give unfettered access to the renderer. This also makes dependencies on types more explicit. For example, the GPU class doesn't need to depend on the existence of a renderer, it only needs to care about whether or not it has a rasterizer, but since it was accessing the global variable, it was also making the renderer a part of its dependency chain. By adjusting the interface, we can get rid of this dependency.
This commit is contained in:
parent
762fcaf5de
commit
6030c5ce41
19 changed files with 101 additions and 75 deletions
|
@ -19,8 +19,8 @@ namespace Engines {
|
|||
/// First register id that is actually a Macro call.
|
||||
constexpr u32 MacroRegistersStart = 0xE00;
|
||||
|
||||
Maxwell3D::Maxwell3D(MemoryManager& memory_manager)
|
||||
: memory_manager(memory_manager), macro_interpreter(*this) {}
|
||||
Maxwell3D::Maxwell3D(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager)
|
||||
: memory_manager(memory_manager), rasterizer{rasterizer}, macro_interpreter(*this) {}
|
||||
|
||||
void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) {
|
||||
auto macro_code = uploaded_macros.find(method);
|
||||
|
@ -130,7 +130,7 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
|
|||
break;
|
||||
}
|
||||
|
||||
VideoCore::g_renderer->Rasterizer()->NotifyMaxwellRegisterChanged(method);
|
||||
rasterizer.NotifyMaxwellRegisterChanged(method);
|
||||
|
||||
if (debug_context) {
|
||||
debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandProcessed, nullptr);
|
||||
|
@ -218,7 +218,7 @@ void Maxwell3D::DrawArrays() {
|
|||
}
|
||||
|
||||
const bool is_indexed{regs.index_array.count && !regs.vertex_buffer.count};
|
||||
VideoCore::g_renderer->Rasterizer()->AccelerateDrawBatch(is_indexed);
|
||||
rasterizer.AccelerateDrawBatch(is_indexed);
|
||||
|
||||
// TODO(bunnei): Below, we reset vertex count so that we can use these registers to determine if
|
||||
// the game is trying to draw indexed or direct mode. This needs to be verified on HW still -
|
||||
|
@ -393,7 +393,7 @@ void Maxwell3D::ProcessClearBuffers() {
|
|||
regs.clear_buffers.R == regs.clear_buffers.B &&
|
||||
regs.clear_buffers.R == regs.clear_buffers.A);
|
||||
|
||||
VideoCore::g_renderer->Rasterizer()->Clear();
|
||||
rasterizer.Clear();
|
||||
}
|
||||
|
||||
} // namespace Engines
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
#include "video_core/memory_manager.h"
|
||||
#include "video_core/textures/texture.h"
|
||||
|
||||
namespace VideoCore {
|
||||
class RasterizerInterface;
|
||||
}
|
||||
|
||||
namespace Tegra::Engines {
|
||||
|
||||
#define MAXWELL3D_REG_INDEX(field_name) \
|
||||
|
@ -24,7 +28,7 @@ namespace Tegra::Engines {
|
|||
|
||||
class Maxwell3D final {
|
||||
public:
|
||||
explicit Maxwell3D(MemoryManager& memory_manager);
|
||||
explicit Maxwell3D(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager);
|
||||
~Maxwell3D() = default;
|
||||
|
||||
/// Register structure of the Maxwell3D engine.
|
||||
|
@ -818,6 +822,8 @@ public:
|
|||
Texture::FullTextureInfo GetStageTexture(Regs::ShaderStage stage, size_t offset) const;
|
||||
|
||||
private:
|
||||
VideoCore::RasterizerInterface& rasterizer;
|
||||
|
||||
std::unordered_map<u32, std::vector<u32>> uploaded_macros;
|
||||
|
||||
/// Macro method that is currently being executed / being fed parameters.
|
||||
|
|
|
@ -7,12 +7,13 @@
|
|||
#include "video_core/engines/maxwell_compute.h"
|
||||
#include "video_core/engines/maxwell_dma.h"
|
||||
#include "video_core/gpu.h"
|
||||
#include "video_core/rasterizer_interface.h"
|
||||
|
||||
namespace Tegra {
|
||||
|
||||
GPU::GPU() {
|
||||
GPU::GPU(VideoCore::RasterizerInterface& rasterizer) {
|
||||
memory_manager = std::make_unique<MemoryManager>();
|
||||
maxwell_3d = std::make_unique<Engines::Maxwell3D>(*memory_manager);
|
||||
maxwell_3d = std::make_unique<Engines::Maxwell3D>(rasterizer, *memory_manager);
|
||||
fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager);
|
||||
maxwell_compute = std::make_unique<Engines::MaxwellCompute>();
|
||||
maxwell_dma = std::make_unique<Engines::MaxwellDMA>(*memory_manager);
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
#include "core/hle/service/nvflinger/buffer_queue.h"
|
||||
#include "video_core/memory_manager.h"
|
||||
|
||||
namespace VideoCore {
|
||||
class RasterizerInterface;
|
||||
}
|
||||
|
||||
namespace Tegra {
|
||||
|
||||
enum class RenderTargetFormat : u32 {
|
||||
|
@ -98,7 +102,7 @@ enum class EngineID {
|
|||
|
||||
class GPU final {
|
||||
public:
|
||||
GPU();
|
||||
explicit GPU(VideoCore::RasterizerInterface& rasterizer);
|
||||
~GPU();
|
||||
|
||||
/// Processes a command list stored at the specified address in GPU memory.
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include "video_core/renderer_base.h"
|
||||
#include "video_core/renderer_opengl/gl_rasterizer.h"
|
||||
|
||||
namespace VideoCore {
|
||||
|
||||
RendererBase::RendererBase(EmuWindow& window) : render_window{window} {}
|
||||
RendererBase::~RendererBase() = default;
|
||||
|
||||
|
@ -21,3 +23,5 @@ void RendererBase::RefreshRasterizerSetting() {
|
|||
rasterizer = std::make_unique<RasterizerOpenGL>(render_window);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace VideoCore
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
class EmuWindow;
|
||||
|
||||
namespace VideoCore {
|
||||
|
||||
class RendererBase : NonCopyable {
|
||||
public:
|
||||
/// Used to reference a framebuffer
|
||||
|
@ -44,7 +46,7 @@ public:
|
|||
return m_current_frame;
|
||||
}
|
||||
|
||||
VideoCore::RasterizerInterface* Rasterizer() const {
|
||||
RasterizerInterface* Rasterizer() const {
|
||||
return rasterizer.get();
|
||||
}
|
||||
|
||||
|
@ -52,7 +54,9 @@ public:
|
|||
|
||||
protected:
|
||||
EmuWindow& render_window; ///< Reference to the render window handle.
|
||||
std::unique_ptr<VideoCore::RasterizerInterface> rasterizer;
|
||||
std::unique_ptr<RasterizerInterface> rasterizer;
|
||||
f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer
|
||||
int m_current_frame = 0; ///< Current frame, should be set by the renderer
|
||||
};
|
||||
|
||||
} // namespace VideoCore
|
||||
|
|
|
@ -103,7 +103,7 @@ ScopeAcquireGLContext::~ScopeAcquireGLContext() {
|
|||
}
|
||||
}
|
||||
|
||||
RendererOpenGL::RendererOpenGL(EmuWindow& window) : RendererBase{window} {}
|
||||
RendererOpenGL::RendererOpenGL(EmuWindow& window) : VideoCore::RendererBase{window} {}
|
||||
RendererOpenGL::~RendererOpenGL() = default;
|
||||
|
||||
/// Swap buffers (render frame)
|
||||
|
|
|
@ -41,7 +41,7 @@ private:
|
|||
EmuWindow& emu_window;
|
||||
};
|
||||
|
||||
class RendererOpenGL : public RendererBase {
|
||||
class RendererOpenGL : public VideoCore::RendererBase {
|
||||
public:
|
||||
explicit RendererOpenGL(EmuWindow& window);
|
||||
~RendererOpenGL() override;
|
||||
|
|
|
@ -3,37 +3,16 @@
|
|||
// Refer to the license.txt file included.
|
||||
|
||||
#include <memory>
|
||||
#include "common/logging/log.h"
|
||||
#include "video_core/renderer_base.h"
|
||||
#include "video_core/renderer_opengl/renderer_opengl.h"
|
||||
#include "video_core/video_core.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Video Core namespace
|
||||
|
||||
namespace VideoCore {
|
||||
|
||||
std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin
|
||||
|
||||
std::atomic<bool> g_toggle_framelimit_enabled;
|
||||
|
||||
/// Initialize the video core
|
||||
bool Init(EmuWindow& emu_window) {
|
||||
g_renderer = std::make_unique<RendererOpenGL>(emu_window);
|
||||
if (g_renderer->Init()) {
|
||||
LOG_DEBUG(Render, "initialized OK");
|
||||
} else {
|
||||
LOG_CRITICAL(Render, "initialization failed !");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Shutdown the video core
|
||||
void Shutdown() {
|
||||
g_renderer.reset();
|
||||
|
||||
LOG_DEBUG(Render, "shutdown OK");
|
||||
std::unique_ptr<RendererBase> CreateRenderer(EmuWindow& emu_window) {
|
||||
return std::make_unique<RendererOpenGL>(emu_window);
|
||||
}
|
||||
|
||||
} // namespace VideoCore
|
||||
|
|
|
@ -8,25 +8,23 @@
|
|||
#include <memory>
|
||||
|
||||
class EmuWindow;
|
||||
class RendererBase;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Video Core namespace
|
||||
|
||||
namespace VideoCore {
|
||||
|
||||
enum class Renderer { Software, OpenGL };
|
||||
class RendererBase;
|
||||
|
||||
extern std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin
|
||||
enum class Renderer { Software, OpenGL };
|
||||
|
||||
// TODO: Wrap these in a user settings struct along with any other graphics settings (often set from
|
||||
// qt ui)
|
||||
extern std::atomic<bool> g_toggle_framelimit_enabled;
|
||||
|
||||
/// Initialize the video core
|
||||
bool Init(EmuWindow& emu_window);
|
||||
|
||||
/// Shutdown the video core
|
||||
void Shutdown();
|
||||
/**
|
||||
* Creates a renderer instance.
|
||||
*
|
||||
* @note The returned renderer instance is simply allocated. Its Init()
|
||||
* function still needs to be called to fully complete its setup.
|
||||
*/
|
||||
std::unique_ptr<RendererBase> CreateRenderer(EmuWindow& emu_window);
|
||||
|
||||
} // namespace VideoCore
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue