diff options
Diffstat (limited to 'src/video_core')
-rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 10 | ||||
-rw-r--r-- | src/video_core/engines/maxwell_3d.h | 8 | ||||
-rw-r--r-- | src/video_core/gpu.cpp | 5 | ||||
-rw-r--r-- | src/video_core/gpu.h | 6 | ||||
-rw-r--r-- | src/video_core/renderer_base.cpp | 4 | ||||
-rw-r--r-- | src/video_core/renderer_base.h | 14 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 10 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 7 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 6 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.h | 2 | ||||
-rw-r--r-- | src/video_core/video_core.cpp | 25 | ||||
-rw-r--r-- | src/video_core/video_core.h | 20 |
12 files changed, 63 insertions, 54 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 0e205ed72..a235b543e 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -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 diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 3c32f1067..4d0ff96a5 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -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. diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 141e20444..b2a83ce0b 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -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); diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 08aa75503..440505c9d 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -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. diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp index dbe3edf09..3ca350243 100644 --- a/src/video_core/renderer_base.cpp +++ b/src/video_core/renderer_base.cpp @@ -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 diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index 1cb161b7f..235de23a1 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h @@ -13,6 +13,8 @@ class EmuWindow; +namespace VideoCore { + class RendererBase : NonCopyable { public: /// Used to reference a framebuffer @@ -44,15 +46,21 @@ public: return m_current_frame; } - VideoCore::RasterizerInterface* Rasterizer() const { - return rasterizer.get(); + RasterizerInterface& Rasterizer() { + return *rasterizer; + } + + const RasterizerInterface& Rasterizer() const { + return *rasterizer; } void RefreshRasterizerSetting(); 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 diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 6555db5bb..c2a931469 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -169,8 +169,14 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, ASSERT(buffer.IsEnabled()); glEnableVertexAttribArray(index); - glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), - attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset); + if (attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::SignedInt || + attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::UnsignedInt) { + glVertexAttribIFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), + attrib.offset); + } else { + glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), + attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset); + } glVertexAttribBinding(index, attrib.buffer); } diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 68db3c22a..e3217db81 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -766,13 +766,16 @@ private: // goes into gpr28+0 and gpr28+1 size_t texs_offset{}; + size_t src_elem{}; for (const auto& dest : {instr.gpr0.Value(), instr.gpr28.Value()}) { + size_t dest_elem{}; for (unsigned elem = 0; elem < 2; ++elem) { - if (!instr.texs.IsComponentEnabled(elem)) { + if (!instr.texs.IsComponentEnabled(src_elem++)) { // Skip disabled components continue; } - regs.SetRegisterToFloat(dest, elem + texs_offset, texture, 1, 4, false, elem); + regs.SetRegisterToFloat(dest, elem + texs_offset, texture, 1, 4, false, + dest_elem++); } if (!instr.texs.HasTwoDestinations()) { diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 74383c7cf..bf9131193 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -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) @@ -160,8 +160,8 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf // only allows rows to have a memory alignement of 4. ASSERT(framebuffer.stride % 4 == 0); - if (!Rasterizer()->AccelerateDisplay(framebuffer, framebuffer_addr, framebuffer.stride, - screen_info)) { + if (!rasterizer->AccelerateDisplay(framebuffer, framebuffer_addr, framebuffer.stride, + screen_info)) { // Reset the screen info's display texture to its own permanent texture screen_info.display_texture = screen_info.texture.resource.handle; diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index ab7de41c8..428afa3b7 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h @@ -41,7 +41,7 @@ private: EmuWindow& emu_window; }; -class RendererOpenGL : public RendererBase { +class RendererOpenGL : public VideoCore::RendererBase { public: explicit RendererOpenGL(EmuWindow& window); ~RendererOpenGL() override; diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index 06b13e681..5085ef96b 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp @@ -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 diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h index 519b757f5..7c01c0b8d 100644 --- a/src/video_core/video_core.h +++ b/src/video_core/video_core.h @@ -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 |