diff options
author | Yuri Kunde Schlesner <yuriks@yuriks.net> | 2015-12-08 05:21:06 +0100 |
---|---|---|
committer | Yuri Kunde Schlesner <yuriks@yuriks.net> | 2015-12-08 05:21:06 +0100 |
commit | 31764c48fb8f78b998b6627ef4ea4f1b2ec83903 (patch) | |
tree | 61533db5c3b250e4f3bc557e442b589e307201ca /src/video_core | |
parent | Merge pull request #1271 from lioncash/dyncom-misc (diff) | |
parent | VideoCore: Unify interface to OpenGL and SW rasterizers (diff) | |
download | yuzu-31764c48fb8f78b998b6627ef4ea4f1b2ec83903.tar yuzu-31764c48fb8f78b998b6627ef4ea4f1b2ec83903.tar.gz yuzu-31764c48fb8f78b998b6627ef4ea4f1b2ec83903.tar.bz2 yuzu-31764c48fb8f78b998b6627ef4ea4f1b2ec83903.tar.lz yuzu-31764c48fb8f78b998b6627ef4ea4f1b2ec83903.tar.xz yuzu-31764c48fb8f78b998b6627ef4ea4f1b2ec83903.tar.zst yuzu-31764c48fb8f78b998b6627ef4ea4f1b2ec83903.zip |
Diffstat (limited to 'src/video_core')
-rw-r--r-- | src/video_core/CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/video_core/clipper.cpp | 2 | ||||
-rw-r--r-- | src/video_core/clipper.h | 2 | ||||
-rw-r--r-- | src/video_core/command_processor.cpp | 27 | ||||
-rw-r--r-- | src/video_core/debug_utils/debug_utils.cpp | 6 | ||||
-rw-r--r-- | src/video_core/rasterizer_interface.h (renamed from src/video_core/hwrasterizer_base.h) | 19 | ||||
-rw-r--r-- | src/video_core/renderer_base.cpp | 28 | ||||
-rw-r--r-- | src/video_core/renderer_base.h | 8 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 23 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 25 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 7 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 8 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 15 | ||||
-rw-r--r-- | src/video_core/swrasterizer.cpp | 16 | ||||
-rw-r--r-- | src/video_core/swrasterizer.h | 26 |
15 files changed, 127 insertions, 90 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 2a924f4ad..c3d7294d5 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -11,8 +11,10 @@ set(SRCS pica.cpp primitive_assembly.cpp rasterizer.cpp + renderer_base.cpp shader/shader.cpp shader/shader_interpreter.cpp + swrasterizer.cpp utils.cpp video_core.cpp ) @@ -30,13 +32,14 @@ set(HEADERS clipper.h command_processor.h gpu_debugger.h - hwrasterizer_base.h pica.h primitive_assembly.h rasterizer.h + rasterizer_interface.h renderer_base.h shader/shader.h shader/shader_interpreter.h + swrasterizer.h utils.h video_core.h ) diff --git a/src/video_core/clipper.cpp b/src/video_core/clipper.cpp index ed99c4f13..5d609da06 100644 --- a/src/video_core/clipper.cpp +++ b/src/video_core/clipper.cpp @@ -78,7 +78,7 @@ static void InitScreenCoordinates(OutputVertex& vtx) vtx.screenpos[2] = viewport.offset_z + vtx.pos.z * inv_w * viewport.zscale; } -void ProcessTriangle(OutputVertex &v0, OutputVertex &v1, OutputVertex &v2) { +void ProcessTriangle(const OutputVertex &v0, const OutputVertex &v1, const OutputVertex &v2) { using boost::container::static_vector; // Clipping a planar n-gon against a plane will remove at least 1 vertex and introduces 2 at diff --git a/src/video_core/clipper.h b/src/video_core/clipper.h index 6ed01e877..f85d8d4c9 100644 --- a/src/video_core/clipper.h +++ b/src/video_core/clipper.h @@ -14,7 +14,7 @@ namespace Clipper { using Shader::OutputVertex; -void ProcessTriangle(OutputVertex& v0, OutputVertex& v1, OutputVertex& v2); +void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const OutputVertex& v2); } // namespace diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index bd1b09a4b..35b976c60 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -336,19 +336,14 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { } } - if (Settings::values.use_hw_renderer) { - // Send to hardware renderer - static auto AddHWTriangle = [](const Pica::Shader::OutputVertex& v0, - const Pica::Shader::OutputVertex& v1, - const Pica::Shader::OutputVertex& v2) { - VideoCore::g_renderer->hw_rasterizer->AddTriangle(v0, v1, v2); - }; - - primitive_assembler.SubmitVertex(output, AddHWTriangle); - } else { - // Send to triangle clipper - primitive_assembler.SubmitVertex(output, Clipper::ProcessTriangle); - } + // Send to renderer + using Pica::Shader::OutputVertex; + auto AddTriangle = []( + const OutputVertex& v0, const OutputVertex& v1, const OutputVertex& v2) { + VideoCore::g_renderer->rasterizer->AddTriangle(v0, v1, v2); + }; + + primitive_assembler.SubmitVertex(output, AddTriangle); } for (auto& range : memory_accesses.ranges) { @@ -356,9 +351,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { range.second, range.first); } - if (Settings::values.use_hw_renderer) { - VideoCore::g_renderer->hw_rasterizer->DrawTriangles(); - } + VideoCore::g_renderer->rasterizer->DrawTriangles(); #if PICA_DUMP_GEOMETRY geometry_dumper.Dump(); @@ -475,7 +468,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { break; } - VideoCore::g_renderer->hw_rasterizer->NotifyPicaRegisterChanged(id); + VideoCore::g_renderer->rasterizer->NotifyPicaRegisterChanged(id); if (g_debug_context) g_debug_context->OnEvent(DebugContext::Event::PicaCommandProcessed, reinterpret_cast<void*>(&id)); diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index f1cfa9361..4f66dbd65 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp @@ -46,10 +46,8 @@ void DebugContext::OnEvent(Event event, void* data) { { std::unique_lock<std::mutex> lock(breakpoint_mutex); - if (Settings::values.use_hw_renderer) { - // Commit the hardware renderer's framebuffer so it will show on debug widgets - VideoCore::g_renderer->hw_rasterizer->CommitFramebuffer(); - } + // Commit the hardware renderer's framebuffer so it will show on debug widgets + VideoCore::g_renderer->rasterizer->FlushFramebuffer(); // TODO: Should stop the CPU thread here once we multithread emulation. diff --git a/src/video_core/hwrasterizer_base.h b/src/video_core/rasterizer_interface.h index 54b8892fb..008c5827b 100644 --- a/src/video_core/hwrasterizer_base.h +++ b/src/video_core/rasterizer_interface.h @@ -12,10 +12,11 @@ struct OutputVertex; } } -class HWRasterizer { +namespace VideoCore { + +class RasterizerInterface { public: - virtual ~HWRasterizer() { - } + virtual ~RasterizerInterface() {} /// Initialize API-specific GPU objects virtual void InitObjects() = 0; @@ -32,14 +33,16 @@ public: virtual void DrawTriangles() = 0; /// Commit the rasterizer's framebuffer contents immediately to the current 3DS memory framebuffer - virtual void CommitFramebuffer() = 0; + virtual void FlushFramebuffer() = 0; /// Notify rasterizer that the specified PICA register has been changed virtual void NotifyPicaRegisterChanged(u32 id) = 0; - /// Notify rasterizer that the specified 3DS memory region will be read from after this notification - virtual void NotifyPreRead(PAddr addr, u32 size) = 0; + /// Notify rasterizer that any caches of the specified region should be flushed to 3DS memory. + virtual void FlushRegion(PAddr addr, u32 size) = 0; - /// Notify rasterizer that a 3DS memory region has been changed - virtual void NotifyFlush(PAddr addr, u32 size) = 0; + /// Notify rasterizer that any caches of the specified region should be discraded and reloaded from 3DS memory. + virtual void InvalidateRegion(PAddr addr, u32 size) = 0; }; + +} diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp new file mode 100644 index 000000000..93e980216 --- /dev/null +++ b/src/video_core/renderer_base.cpp @@ -0,0 +1,28 @@ +// Copyright 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <memory> + +#include "common/make_unique.h" + +#include "core/settings.h" + +#include "video_core/renderer_base.h" +#include "video_core/video_core.h" +#include "video_core/swrasterizer.h" +#include "video_core/renderer_opengl/gl_rasterizer.h" + +void RendererBase::RefreshRasterizerSetting() { + bool hw_renderer_enabled = VideoCore::g_hw_renderer_enabled; + if (rasterizer == nullptr || opengl_rasterizer_active != hw_renderer_enabled) { + opengl_rasterizer_active = hw_renderer_enabled; + + if (hw_renderer_enabled) { + rasterizer = Common::make_unique<RasterizerOpenGL>(); + } else { + rasterizer = Common::make_unique<VideoCore::SWRasterizer>(); + } + rasterizer->InitObjects(); + } +} diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index 6587bcf27..506bff815 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h @@ -8,7 +8,7 @@ #include "common/common_types.h" -#include "video_core/hwrasterizer_base.h" +#include "video_core/rasterizer_interface.h" class EmuWindow; @@ -54,10 +54,14 @@ public: return m_current_frame; } - std::unique_ptr<HWRasterizer> hw_rasterizer; + void RefreshRasterizerSetting(); + + std::unique_ptr<VideoCore::RasterizerInterface> rasterizer; protected: f32 m_current_fps; ///< Current framerate, should be set by the renderer int m_current_frame; ///< Current frame, should be set by the renderer +private: + bool opengl_rasterizer_active = false; }; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 822739088..681fdca8d 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -135,7 +135,7 @@ void RasterizerOpenGL::Reset() { SetShader(); - res_cache.FullFlush(); + res_cache.InvalidateAll(); } void RasterizerOpenGL::AddTriangle(const Pica::Shader::OutputVertex& v0, @@ -176,11 +176,11 @@ void RasterizerOpenGL::DrawTriangles() { u32 cur_fb_depth_size = Pica::Regs::BytesPerDepthPixel(regs.framebuffer.depth_format) * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight(); - res_cache.NotifyFlush(cur_fb_color_addr, cur_fb_color_size, true); - res_cache.NotifyFlush(cur_fb_depth_addr, cur_fb_depth_size, true); + res_cache.InvalidateInRange(cur_fb_color_addr, cur_fb_color_size, true); + res_cache.InvalidateInRange(cur_fb_depth_addr, cur_fb_depth_size, true); } -void RasterizerOpenGL::CommitFramebuffer() { +void RasterizerOpenGL::FlushFramebuffer() { CommitColorBuffer(); CommitDepthBuffer(); } @@ -188,9 +188,6 @@ void RasterizerOpenGL::CommitFramebuffer() { void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { const auto& regs = Pica::g_state.regs; - if (!Settings::values.use_hw_renderer) - return; - switch(id) { // Culling case PICA_REG_INDEX(cull_mode): @@ -284,12 +281,9 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { } } -void RasterizerOpenGL::NotifyPreRead(PAddr addr, u32 size) { +void RasterizerOpenGL::FlushRegion(PAddr addr, u32 size) { const auto& regs = Pica::g_state.regs; - if (!Settings::values.use_hw_renderer) - return; - PAddr cur_fb_color_addr = regs.framebuffer.GetColorBufferPhysicalAddress(); u32 cur_fb_color_size = Pica::Regs::BytesPerColorPixel(regs.framebuffer.color_format) * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight(); @@ -306,12 +300,9 @@ void RasterizerOpenGL::NotifyPreRead(PAddr addr, u32 size) { CommitDepthBuffer(); } -void RasterizerOpenGL::NotifyFlush(PAddr addr, u32 size) { +void RasterizerOpenGL::InvalidateRegion(PAddr addr, u32 size) { const auto& regs = Pica::g_state.regs; - if (!Settings::values.use_hw_renderer) - return; - PAddr cur_fb_color_addr = regs.framebuffer.GetColorBufferPhysicalAddress(); u32 cur_fb_color_size = Pica::Regs::BytesPerColorPixel(regs.framebuffer.color_format) * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight(); @@ -328,7 +319,7 @@ void RasterizerOpenGL::NotifyFlush(PAddr addr, u32 size) { ReloadDepthBuffer(); // Notify cache of flush in case the region touches a cached resource - res_cache.NotifyFlush(addr, size); + res_cache.InvalidateInRange(addr, size); } void RasterizerOpenGL::SamplerInfo::Create() { diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 5ba898189..92b1f812e 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -14,7 +14,7 @@ #include "common/hash.h" #include "video_core/pica.h" -#include "video_core/hwrasterizer_base.h" +#include "video_core/rasterizer_interface.h" #include "video_core/renderer_opengl/gl_rasterizer_cache.h" #include "video_core/renderer_opengl/gl_state.h" #include "video_core/shader/shader_interpreter.h" @@ -102,37 +102,22 @@ struct hash<PicaShaderConfig> { } // namespace std -class RasterizerOpenGL : public HWRasterizer { +class RasterizerOpenGL : public VideoCore::RasterizerInterface { public: RasterizerOpenGL(); ~RasterizerOpenGL() override; - /// Initialize API-specific GPU objects void InitObjects() override; - - /// Reset the rasterizer, such as flushing all caches and updating all state void Reset() override; - - /// Queues the primitive formed by the given vertices for rendering void AddTriangle(const Pica::Shader::OutputVertex& v0, const Pica::Shader::OutputVertex& v1, const Pica::Shader::OutputVertex& v2) override; - - /// Draw the current batch of triangles void DrawTriangles() override; - - /// Commit the rasterizer's framebuffer contents immediately to the current 3DS memory framebuffer - void CommitFramebuffer() override; - - /// Notify rasterizer that the specified PICA register has been changed + void FlushFramebuffer() override; void NotifyPicaRegisterChanged(u32 id) override; - - /// Notify rasterizer that the specified 3DS memory region will be read from after this notification - void NotifyPreRead(PAddr addr, u32 size) override; - - /// Notify rasterizer that a 3DS memory region has been changed - void NotifyFlush(PAddr addr, u32 size) override; + void FlushRegion(PAddr addr, u32 size) override; + void InvalidateRegion(PAddr addr, u32 size) override; /// OpenGL shader generated for a given Pica register state struct PicaShader { diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 10d4ab0b6..a9ad46fe0 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -15,7 +15,7 @@ #include "video_core/renderer_opengl/pica_to_gl.h" RasterizerCacheOpenGL::~RasterizerCacheOpenGL() { - FullFlush(); + InvalidateAll(); } MICROPROFILE_DEFINE(OpenGL_TextureUpload, "OpenGL", "Texture Upload", MP_RGB(128, 64, 192)); @@ -58,8 +58,7 @@ void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned text } } -void RasterizerCacheOpenGL::NotifyFlush(PAddr addr, u32 size, bool ignore_hash) { - // Flush any texture that falls in the flushed region +void RasterizerCacheOpenGL::InvalidateInRange(PAddr addr, u32 size, bool ignore_hash) { // TODO: Optimize by also inserting upper bound (addr + size) of each texture into the same map and also narrow using lower_bound auto cache_upper_bound = texture_cache.upper_bound(addr + size); @@ -77,6 +76,6 @@ void RasterizerCacheOpenGL::NotifyFlush(PAddr addr, u32 size, bool ignore_hash) } } -void RasterizerCacheOpenGL::FullFlush() { +void RasterizerCacheOpenGL::InvalidateAll() { texture_cache.clear(); } diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 98a48ffbe..b69651427 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -23,11 +23,11 @@ public: LoadAndBindTexture(state, texture_unit, Pica::DebugUtils::TextureInfo::FromPicaRegister(config.config, config.format)); } - /// Flush any cached resource that touches the flushed region - void NotifyFlush(PAddr addr, u32 size, bool ignore_hash = false); + /// Invalidate any cached resource intersecting the specified region. + void InvalidateInRange(PAddr addr, u32 size, bool ignore_hash = false); - /// Flush all cached OpenGL resources tracked by this cache manager - void FullFlush(); + /// Invalidate all cached OpenGL resources tracked by this cache manager + void InvalidateAll(); private: struct CachedTexture { diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 1420229cc..c14bdb8ab 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -93,7 +93,6 @@ static std::array<GLfloat, 3*2> MakeOrthographicMatrix(const float width, const /// RendererOpenGL constructor RendererOpenGL::RendererOpenGL() { - hw_rasterizer.reset(new RasterizerOpenGL()); resolution_width = std::max(VideoCore::kScreenTopWidth, VideoCore::kScreenBottomWidth); resolution_height = VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight; } @@ -157,15 +156,7 @@ void RendererOpenGL::SwapBuffers() { profiler.BeginFrame(); - bool hw_renderer_enabled = VideoCore::g_hw_renderer_enabled; - if (Settings::values.use_hw_renderer != hw_renderer_enabled) { - // TODO: Save new setting value to config file for next startup - Settings::values.use_hw_renderer = hw_renderer_enabled; - - if (Settings::values.use_hw_renderer) { - hw_rasterizer->Reset(); - } - } + RefreshRasterizerSetting(); if (Pica::g_debug_context && Pica::g_debug_context->recorder) { Pica::g_debug_context->recorder->FrameFinished(); @@ -286,8 +277,6 @@ void RendererOpenGL::InitOpenGLObjects() { state.texture_units[0].texture_2d = 0; state.Apply(); - - hw_rasterizer->InitObjects(); } void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, @@ -419,6 +408,8 @@ void RendererOpenGL::Init() { LOG_INFO(Render_OpenGL, "GL_VENDOR: %s", glGetString(GL_VENDOR)); LOG_INFO(Render_OpenGL, "GL_RENDERER: %s", glGetString(GL_RENDERER)); InitOpenGLObjects(); + + RefreshRasterizerSetting(); } /// Shutdown the renderer diff --git a/src/video_core/swrasterizer.cpp b/src/video_core/swrasterizer.cpp new file mode 100644 index 000000000..03df15b01 --- /dev/null +++ b/src/video_core/swrasterizer.cpp @@ -0,0 +1,16 @@ +// Copyright 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "video_core/clipper.h" +#include "video_core/swrasterizer.h" + +namespace VideoCore { + +void SWRasterizer::AddTriangle(const Pica::Shader::OutputVertex& v0, + const Pica::Shader::OutputVertex& v1, + const Pica::Shader::OutputVertex& v2) { + Pica::Clipper::ProcessTriangle(v0, v1, v2); +} + +} diff --git a/src/video_core/swrasterizer.h b/src/video_core/swrasterizer.h new file mode 100644 index 000000000..e9a4e39c6 --- /dev/null +++ b/src/video_core/swrasterizer.h @@ -0,0 +1,26 @@ +// Copyright 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "common/common_types.h" + +#include "video_core/rasterizer_interface.h" + +namespace VideoCore { + +class SWRasterizer : public RasterizerInterface { + void InitObjects() override {} + void Reset() override {} + void AddTriangle(const Pica::Shader::OutputVertex& v0, + const Pica::Shader::OutputVertex& v1, + const Pica::Shader::OutputVertex& v2); + void DrawTriangles() override {} + void FlushFramebuffer() override {} + void NotifyPicaRegisterChanged(u32 id) override {} + void FlushRegion(PAddr addr, u32 size) override {} + void InvalidateRegion(PAddr addr, u32 size) override {} +}; + +} |