mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Merge pull request #1272 from yuriks/merge-rasterizer
VideoCore: Unify interface to OpenGL and SW rasterizers
This commit is contained in:
		
						commit
						31764c48fb
					
				
					 18 changed files with 137 additions and 100 deletions
				
			
		|  | @ -275,7 +275,7 @@ static void FlushDataCache(Service::Interface* self) { | ||||||
|     u32 size    = cmd_buff[2]; |     u32 size    = cmd_buff[2]; | ||||||
|     u32 process = cmd_buff[4]; |     u32 process = cmd_buff[4]; | ||||||
| 
 | 
 | ||||||
|     VideoCore::g_renderer->hw_rasterizer->NotifyFlush(Memory::VirtualToPhysicalAddress(address), size); |     VideoCore::g_renderer->rasterizer->InvalidateRegion(Memory::VirtualToPhysicalAddress(address), size); | ||||||
| 
 | 
 | ||||||
|     // TODO(purpasmart96): Verify return header on HW
 |     // TODO(purpasmart96): Verify return header on HW
 | ||||||
| 
 | 
 | ||||||
|  | @ -365,7 +365,7 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { | ||||||
| 
 | 
 | ||||||
|     // GX request DMA - typically used for copying memory from GSP heap to VRAM
 |     // GX request DMA - typically used for copying memory from GSP heap to VRAM
 | ||||||
|     case CommandId::REQUEST_DMA: |     case CommandId::REQUEST_DMA: | ||||||
|         VideoCore::g_renderer->hw_rasterizer->NotifyPreRead(Memory::VirtualToPhysicalAddress(command.dma_request.source_address), |         VideoCore::g_renderer->rasterizer->FlushRegion(Memory::VirtualToPhysicalAddress(command.dma_request.source_address), | ||||||
|                                                             command.dma_request.size); |                                                             command.dma_request.size); | ||||||
| 
 | 
 | ||||||
|         memcpy(Memory::GetPointer(command.dma_request.dest_address), |         memcpy(Memory::GetPointer(command.dma_request.dest_address), | ||||||
|  | @ -373,7 +373,7 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { | ||||||
|                command.dma_request.size); |                command.dma_request.size); | ||||||
|         SignalInterrupt(InterruptId::DMA); |         SignalInterrupt(InterruptId::DMA); | ||||||
| 
 | 
 | ||||||
|         VideoCore::g_renderer->hw_rasterizer->NotifyFlush(Memory::VirtualToPhysicalAddress(command.dma_request.dest_address), |         VideoCore::g_renderer->rasterizer->InvalidateRegion(Memory::VirtualToPhysicalAddress(command.dma_request.dest_address), | ||||||
|                                                           command.dma_request.size); |                                                           command.dma_request.size); | ||||||
|         break; |         break; | ||||||
| 
 | 
 | ||||||
|  | @ -467,7 +467,7 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { | ||||||
|             if (region.size == 0) |             if (region.size == 0) | ||||||
|                 break; |                 break; | ||||||
| 
 | 
 | ||||||
|             VideoCore::g_renderer->hw_rasterizer->NotifyFlush( |             VideoCore::g_renderer->rasterizer->InvalidateRegion( | ||||||
|                 Memory::VirtualToPhysicalAddress(region.address), region.size); |                 Memory::VirtualToPhysicalAddress(region.address), region.size); | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|  |  | ||||||
|  | @ -267,7 +267,7 @@ static void StartConversion(Service::Interface* self) { | ||||||
|     // dst_image_size would seem to be perfect for this, but it doesn't include the gap :(
 |     // dst_image_size would seem to be perfect for this, but it doesn't include the gap :(
 | ||||||
|     u32 total_output_size = conversion.input_lines * |     u32 total_output_size = conversion.input_lines * | ||||||
|         (conversion.dst.transfer_unit + conversion.dst.gap); |         (conversion.dst.transfer_unit + conversion.dst.gap); | ||||||
|     VideoCore::g_renderer->hw_rasterizer->NotifyFlush( |     VideoCore::g_renderer->rasterizer->InvalidateRegion( | ||||||
|         Memory::VirtualToPhysicalAddress(conversion.dst.address), total_output_size); |         Memory::VirtualToPhysicalAddress(conversion.dst.address), total_output_size); | ||||||
| 
 | 
 | ||||||
|     LOG_DEBUG(Service_Y2R, "called"); |     LOG_DEBUG(Service_Y2R, "called"); | ||||||
|  |  | ||||||
|  | @ -26,7 +26,7 @@ | ||||||
| #include "core/tracer/recorder.h" | #include "core/tracer/recorder.h" | ||||||
| 
 | 
 | ||||||
| #include "video_core/command_processor.h" | #include "video_core/command_processor.h" | ||||||
| #include "video_core/hwrasterizer_base.h" | #include "video_core/rasterizer_interface.h" | ||||||
| #include "video_core/renderer_base.h" | #include "video_core/renderer_base.h" | ||||||
| #include "video_core/utils.h" | #include "video_core/utils.h" | ||||||
| #include "video_core/video_core.h" | #include "video_core/video_core.h" | ||||||
|  | @ -141,7 +141,7 @@ inline void Write(u32 addr, const T data) { | ||||||
|                     GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC1); |                     GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC1); | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 VideoCore::g_renderer->hw_rasterizer->NotifyFlush(config.GetStartAddress(), config.GetEndAddress() - config.GetStartAddress()); |                 VideoCore::g_renderer->rasterizer->InvalidateRegion(config.GetStartAddress(), config.GetEndAddress() - config.GetStartAddress()); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             // Reset "trigger" flag and set the "finish" flag
 |             // Reset "trigger" flag and set the "finish" flag
 | ||||||
|  | @ -172,7 +172,7 @@ inline void Write(u32 addr, const T data) { | ||||||
|                 u32 output_gap = config.texture_copy.output_gap * 16; |                 u32 output_gap = config.texture_copy.output_gap * 16; | ||||||
| 
 | 
 | ||||||
|                 size_t contiguous_input_size = config.texture_copy.size / input_width * (input_width + input_gap); |                 size_t contiguous_input_size = config.texture_copy.size / input_width * (input_width + input_gap); | ||||||
|                 VideoCore::g_renderer->hw_rasterizer->NotifyPreRead(config.GetPhysicalInputAddress(), contiguous_input_size); |                 VideoCore::g_renderer->rasterizer->FlushRegion(config.GetPhysicalInputAddress(), contiguous_input_size); | ||||||
| 
 | 
 | ||||||
|                 u32 remaining_size = config.texture_copy.size; |                 u32 remaining_size = config.texture_copy.size; | ||||||
|                 u32 remaining_input = input_width; |                 u32 remaining_input = input_width; | ||||||
|  | @ -205,7 +205,7 @@ inline void Write(u32 addr, const T data) { | ||||||
|                     config.flags); |                     config.flags); | ||||||
| 
 | 
 | ||||||
|                 size_t contiguous_output_size = config.texture_copy.size / output_width * (output_width + output_gap); |                 size_t contiguous_output_size = config.texture_copy.size / output_width * (output_width + output_gap); | ||||||
|                 VideoCore::g_renderer->hw_rasterizer->NotifyFlush(config.GetPhysicalOutputAddress(), contiguous_output_size); |                 VideoCore::g_renderer->rasterizer->InvalidateRegion(config.GetPhysicalOutputAddress(), contiguous_output_size); | ||||||
| 
 | 
 | ||||||
|                 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PPF); |                 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PPF); | ||||||
|                 break; |                 break; | ||||||
|  | @ -232,7 +232,7 @@ inline void Write(u32 addr, const T data) { | ||||||
|             u32 input_size = config.input_width * config.input_height * GPU::Regs::BytesPerPixel(config.input_format); |             u32 input_size = config.input_width * config.input_height * GPU::Regs::BytesPerPixel(config.input_format); | ||||||
|             u32 output_size = output_width * output_height * GPU::Regs::BytesPerPixel(config.output_format); |             u32 output_size = output_width * output_height * GPU::Regs::BytesPerPixel(config.output_format); | ||||||
| 
 | 
 | ||||||
|             VideoCore::g_renderer->hw_rasterizer->NotifyPreRead(config.GetPhysicalInputAddress(), input_size); |             VideoCore::g_renderer->rasterizer->FlushRegion(config.GetPhysicalInputAddress(), input_size); | ||||||
| 
 | 
 | ||||||
|             for (u32 y = 0; y < output_height; ++y) { |             for (u32 y = 0; y < output_height; ++y) { | ||||||
|                 for (u32 x = 0; x < output_width; ++x) { |                 for (u32 x = 0; x < output_width; ++x) { | ||||||
|  | @ -339,7 +339,7 @@ inline void Write(u32 addr, const T data) { | ||||||
|             g_regs.display_transfer_config.trigger = 0; |             g_regs.display_transfer_config.trigger = 0; | ||||||
|             GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PPF); |             GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PPF); | ||||||
| 
 | 
 | ||||||
|             VideoCore::g_renderer->hw_rasterizer->NotifyFlush(config.GetPhysicalOutputAddress(), output_size); |             VideoCore::g_renderer->rasterizer->InvalidateRegion(config.GetPhysicalOutputAddress(), output_size); | ||||||
|         } |         } | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -11,8 +11,10 @@ set(SRCS | ||||||
|             pica.cpp |             pica.cpp | ||||||
|             primitive_assembly.cpp |             primitive_assembly.cpp | ||||||
|             rasterizer.cpp |             rasterizer.cpp | ||||||
|  |             renderer_base.cpp | ||||||
|             shader/shader.cpp |             shader/shader.cpp | ||||||
|             shader/shader_interpreter.cpp |             shader/shader_interpreter.cpp | ||||||
|  |             swrasterizer.cpp | ||||||
|             utils.cpp |             utils.cpp | ||||||
|             video_core.cpp |             video_core.cpp | ||||||
|             ) |             ) | ||||||
|  | @ -30,13 +32,14 @@ set(HEADERS | ||||||
|             clipper.h |             clipper.h | ||||||
|             command_processor.h |             command_processor.h | ||||||
|             gpu_debugger.h |             gpu_debugger.h | ||||||
|             hwrasterizer_base.h |  | ||||||
|             pica.h |             pica.h | ||||||
|             primitive_assembly.h |             primitive_assembly.h | ||||||
|             rasterizer.h |             rasterizer.h | ||||||
|  |             rasterizer_interface.h | ||||||
|             renderer_base.h |             renderer_base.h | ||||||
|             shader/shader.h |             shader/shader.h | ||||||
|             shader/shader_interpreter.h |             shader/shader_interpreter.h | ||||||
|  |             swrasterizer.h | ||||||
|             utils.h |             utils.h | ||||||
|             video_core.h |             video_core.h | ||||||
|             ) |             ) | ||||||
|  |  | ||||||
|  | @ -78,7 +78,7 @@ static void InitScreenCoordinates(OutputVertex& vtx) | ||||||
|     vtx.screenpos[2] = viewport.offset_z + vtx.pos.z * inv_w * viewport.zscale; |     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; |     using boost::container::static_vector; | ||||||
| 
 | 
 | ||||||
|     // Clipping a planar n-gon against a plane will remove at least 1 vertex and introduces 2 at
 |     // Clipping a planar n-gon against a plane will remove at least 1 vertex and introduces 2 at
 | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ namespace Clipper { | ||||||
| 
 | 
 | ||||||
| using Shader::OutputVertex; | using Shader::OutputVertex; | ||||||
| 
 | 
 | ||||||
| void ProcessTriangle(OutputVertex& v0, OutputVertex& v1, OutputVertex& v2); | void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const OutputVertex& v2); | ||||||
| 
 | 
 | ||||||
| } // namespace
 | } // namespace
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -336,19 +336,14 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 if (Settings::values.use_hw_renderer) { |                 // Send to renderer
 | ||||||
|                     // Send to hardware renderer
 |                 using Pica::Shader::OutputVertex; | ||||||
|                     static auto AddHWTriangle = [](const Pica::Shader::OutputVertex& v0, |                 auto AddTriangle = []( | ||||||
|                                                    const Pica::Shader::OutputVertex& v1, |                         const OutputVertex& v0, const OutputVertex& v1, const OutputVertex& v2) { | ||||||
|                                                    const Pica::Shader::OutputVertex& v2) { |                     VideoCore::g_renderer->rasterizer->AddTriangle(v0, v1, v2); | ||||||
|                         VideoCore::g_renderer->hw_rasterizer->AddTriangle(v0, v1, v2); |                 }; | ||||||
|                     }; |  | ||||||
| 
 | 
 | ||||||
|                     primitive_assembler.SubmitVertex(output, AddHWTriangle); |                 primitive_assembler.SubmitVertex(output, AddTriangle); | ||||||
|                 } else { |  | ||||||
|                     // Send to triangle clipper
 |  | ||||||
|                     primitive_assembler.SubmitVertex(output, Clipper::ProcessTriangle); |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             for (auto& range : memory_accesses.ranges) { |             for (auto& range : memory_accesses.ranges) { | ||||||
|  | @ -356,9 +351,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | ||||||
|                                                           range.second, range.first); |                                                           range.second, range.first); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (Settings::values.use_hw_renderer) { |             VideoCore::g_renderer->rasterizer->DrawTriangles(); | ||||||
|                 VideoCore::g_renderer->hw_rasterizer->DrawTriangles(); |  | ||||||
|             } |  | ||||||
| 
 | 
 | ||||||
| #if PICA_DUMP_GEOMETRY | #if PICA_DUMP_GEOMETRY | ||||||
|             geometry_dumper.Dump(); |             geometry_dumper.Dump(); | ||||||
|  | @ -475,7 +468,7 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { | ||||||
|             break; |             break; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     VideoCore::g_renderer->hw_rasterizer->NotifyPicaRegisterChanged(id); |     VideoCore::g_renderer->rasterizer->NotifyPicaRegisterChanged(id); | ||||||
| 
 | 
 | ||||||
|     if (g_debug_context) |     if (g_debug_context) | ||||||
|         g_debug_context->OnEvent(DebugContext::Event::PicaCommandProcessed, reinterpret_cast<void*>(&id)); |         g_debug_context->OnEvent(DebugContext::Event::PicaCommandProcessed, reinterpret_cast<void*>(&id)); | ||||||
|  |  | ||||||
|  | @ -46,10 +46,8 @@ void DebugContext::OnEvent(Event event, void* data) { | ||||||
|     { |     { | ||||||
|         std::unique_lock<std::mutex> lock(breakpoint_mutex); |         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
 | ||||||
|             // Commit the hardware renderer's framebuffer so it will show on debug widgets
 |         VideoCore::g_renderer->rasterizer->FlushFramebuffer(); | ||||||
|             VideoCore::g_renderer->hw_rasterizer->CommitFramebuffer(); |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         // TODO: Should stop the CPU thread here once we multithread emulation.
 |         // TODO: Should stop the CPU thread here once we multithread emulation.
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -12,10 +12,11 @@ struct OutputVertex; | ||||||
| } | } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class HWRasterizer { | namespace VideoCore { | ||||||
|  | 
 | ||||||
|  | class RasterizerInterface { | ||||||
| public: | public: | ||||||
|     virtual ~HWRasterizer() { |     virtual ~RasterizerInterface() {} | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     /// Initialize API-specific GPU objects
 |     /// Initialize API-specific GPU objects
 | ||||||
|     virtual void InitObjects() = 0; |     virtual void InitObjects() = 0; | ||||||
|  | @ -32,14 +33,16 @@ public: | ||||||
|     virtual void DrawTriangles() = 0; |     virtual void DrawTriangles() = 0; | ||||||
| 
 | 
 | ||||||
|     /// Commit the rasterizer's framebuffer contents immediately to the current 3DS memory framebuffer
 |     /// 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
 |     /// Notify rasterizer that the specified PICA register has been changed
 | ||||||
|     virtual void NotifyPicaRegisterChanged(u32 id) = 0; |     virtual void NotifyPicaRegisterChanged(u32 id) = 0; | ||||||
| 
 | 
 | ||||||
|     /// Notify rasterizer that the specified 3DS memory region will be read from after this notification
 |     /// Notify rasterizer that any caches of the specified region should be flushed to 3DS memory.
 | ||||||
|     virtual void NotifyPreRead(PAddr addr, u32 size) = 0; |     virtual void FlushRegion(PAddr addr, u32 size) = 0; | ||||||
| 
 | 
 | ||||||
|     /// Notify rasterizer that a 3DS memory region has been changed
 |     /// Notify rasterizer that any caches of the specified region should be discraded and reloaded from 3DS memory.
 | ||||||
|     virtual void NotifyFlush(PAddr addr, u32 size) = 0; |     virtual void InvalidateRegion(PAddr addr, u32 size) = 0; | ||||||
| }; | }; | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										28
									
								
								src/video_core/renderer_base.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/video_core/renderer_base.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -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(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -8,7 +8,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| 
 | 
 | ||||||
| #include "video_core/hwrasterizer_base.h" | #include "video_core/rasterizer_interface.h" | ||||||
| 
 | 
 | ||||||
| class EmuWindow; | class EmuWindow; | ||||||
| 
 | 
 | ||||||
|  | @ -54,10 +54,14 @@ public: | ||||||
|         return m_current_frame; |         return m_current_frame; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     std::unique_ptr<HWRasterizer> hw_rasterizer; |     void RefreshRasterizerSetting(); | ||||||
|  | 
 | ||||||
|  |     std::unique_ptr<VideoCore::RasterizerInterface> rasterizer; | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
|     f32 m_current_fps;              ///< Current framerate, should be set by the renderer
 |     f32 m_current_fps;              ///< Current framerate, should be set by the renderer
 | ||||||
|     int m_current_frame;            ///< Current frame, should be set by the renderer
 |     int m_current_frame;            ///< Current frame, should be set by the renderer
 | ||||||
| 
 | 
 | ||||||
|  | private: | ||||||
|  |     bool opengl_rasterizer_active = false; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -135,7 +135,7 @@ void RasterizerOpenGL::Reset() { | ||||||
| 
 | 
 | ||||||
|     SetShader(); |     SetShader(); | ||||||
| 
 | 
 | ||||||
|     res_cache.FullFlush(); |     res_cache.InvalidateAll(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::AddTriangle(const Pica::Shader::OutputVertex& v0, | 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) |     u32 cur_fb_depth_size = Pica::Regs::BytesPerDepthPixel(regs.framebuffer.depth_format) | ||||||
|                             * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight(); |                             * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight(); | ||||||
| 
 | 
 | ||||||
|     res_cache.NotifyFlush(cur_fb_color_addr, cur_fb_color_size, true); |     res_cache.InvalidateInRange(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_depth_addr, cur_fb_depth_size, true); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::CommitFramebuffer() { | void RasterizerOpenGL::FlushFramebuffer() { | ||||||
|     CommitColorBuffer(); |     CommitColorBuffer(); | ||||||
|     CommitDepthBuffer(); |     CommitDepthBuffer(); | ||||||
| } | } | ||||||
|  | @ -188,9 +188,6 @@ void RasterizerOpenGL::CommitFramebuffer() { | ||||||
| void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { | void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { | ||||||
|     const auto& regs = Pica::g_state.regs; |     const auto& regs = Pica::g_state.regs; | ||||||
| 
 | 
 | ||||||
|     if (!Settings::values.use_hw_renderer) |  | ||||||
|         return; |  | ||||||
| 
 |  | ||||||
|     switch(id) { |     switch(id) { | ||||||
|     // Culling
 |     // Culling
 | ||||||
|     case PICA_REG_INDEX(cull_mode): |     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; |     const auto& regs = Pica::g_state.regs; | ||||||
| 
 | 
 | ||||||
|     if (!Settings::values.use_hw_renderer) |  | ||||||
|         return; |  | ||||||
| 
 |  | ||||||
|     PAddr cur_fb_color_addr = regs.framebuffer.GetColorBufferPhysicalAddress(); |     PAddr cur_fb_color_addr = regs.framebuffer.GetColorBufferPhysicalAddress(); | ||||||
|     u32 cur_fb_color_size = Pica::Regs::BytesPerColorPixel(regs.framebuffer.color_format) |     u32 cur_fb_color_size = Pica::Regs::BytesPerColorPixel(regs.framebuffer.color_format) | ||||||
|                             * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight(); |                             * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight(); | ||||||
|  | @ -306,12 +300,9 @@ void RasterizerOpenGL::NotifyPreRead(PAddr addr, u32 size) { | ||||||
|         CommitDepthBuffer(); |         CommitDepthBuffer(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::NotifyFlush(PAddr addr, u32 size) { | void RasterizerOpenGL::InvalidateRegion(PAddr addr, u32 size) { | ||||||
|     const auto& regs = Pica::g_state.regs; |     const auto& regs = Pica::g_state.regs; | ||||||
| 
 | 
 | ||||||
|     if (!Settings::values.use_hw_renderer) |  | ||||||
|         return; |  | ||||||
| 
 |  | ||||||
|     PAddr cur_fb_color_addr = regs.framebuffer.GetColorBufferPhysicalAddress(); |     PAddr cur_fb_color_addr = regs.framebuffer.GetColorBufferPhysicalAddress(); | ||||||
|     u32 cur_fb_color_size = Pica::Regs::BytesPerColorPixel(regs.framebuffer.color_format) |     u32 cur_fb_color_size = Pica::Regs::BytesPerColorPixel(regs.framebuffer.color_format) | ||||||
|                             * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight(); |                             * regs.framebuffer.GetWidth() * regs.framebuffer.GetHeight(); | ||||||
|  | @ -328,7 +319,7 @@ void RasterizerOpenGL::NotifyFlush(PAddr addr, u32 size) { | ||||||
|         ReloadDepthBuffer(); |         ReloadDepthBuffer(); | ||||||
| 
 | 
 | ||||||
|     // Notify cache of flush in case the region touches a cached resource
 |     // 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() { | void RasterizerOpenGL::SamplerInfo::Create() { | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ | ||||||
| #include "common/hash.h" | #include "common/hash.h" | ||||||
| 
 | 
 | ||||||
| #include "video_core/pica.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_rasterizer_cache.h" | ||||||
| #include "video_core/renderer_opengl/gl_state.h" | #include "video_core/renderer_opengl/gl_state.h" | ||||||
| #include "video_core/shader/shader_interpreter.h" | #include "video_core/shader/shader_interpreter.h" | ||||||
|  | @ -102,37 +102,22 @@ struct hash<PicaShaderConfig> { | ||||||
| 
 | 
 | ||||||
| } // namespace std
 | } // namespace std
 | ||||||
| 
 | 
 | ||||||
| class RasterizerOpenGL : public HWRasterizer { | class RasterizerOpenGL : public VideoCore::RasterizerInterface { | ||||||
| public: | public: | ||||||
| 
 | 
 | ||||||
|     RasterizerOpenGL(); |     RasterizerOpenGL(); | ||||||
|     ~RasterizerOpenGL() override; |     ~RasterizerOpenGL() override; | ||||||
| 
 | 
 | ||||||
|     /// Initialize API-specific GPU objects
 |  | ||||||
|     void InitObjects() override; |     void InitObjects() override; | ||||||
| 
 |  | ||||||
|     /// Reset the rasterizer, such as flushing all caches and updating all state
 |  | ||||||
|     void Reset() override; |     void Reset() override; | ||||||
| 
 |  | ||||||
|     /// Queues the primitive formed by the given vertices for rendering
 |  | ||||||
|     void AddTriangle(const Pica::Shader::OutputVertex& v0, |     void AddTriangle(const Pica::Shader::OutputVertex& v0, | ||||||
|                      const Pica::Shader::OutputVertex& v1, |                      const Pica::Shader::OutputVertex& v1, | ||||||
|                      const Pica::Shader::OutputVertex& v2) override; |                      const Pica::Shader::OutputVertex& v2) override; | ||||||
| 
 |  | ||||||
|     /// Draw the current batch of triangles
 |  | ||||||
|     void DrawTriangles() override; |     void DrawTriangles() override; | ||||||
| 
 |     void FlushFramebuffer() 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 NotifyPicaRegisterChanged(u32 id) override; |     void NotifyPicaRegisterChanged(u32 id) override; | ||||||
| 
 |     void FlushRegion(PAddr addr, u32 size) override; | ||||||
|     /// Notify rasterizer that the specified 3DS memory region will be read from after this notification
 |     void InvalidateRegion(PAddr addr, u32 size) override; | ||||||
|     void NotifyPreRead(PAddr addr, u32 size) override; |  | ||||||
| 
 |  | ||||||
|     /// Notify rasterizer that a 3DS memory region has been changed
 |  | ||||||
|     void NotifyFlush(PAddr addr, u32 size) override; |  | ||||||
| 
 | 
 | ||||||
|     /// OpenGL shader generated for a given Pica register state
 |     /// OpenGL shader generated for a given Pica register state
 | ||||||
|     struct PicaShader { |     struct PicaShader { | ||||||
|  |  | ||||||
|  | @ -15,7 +15,7 @@ | ||||||
| #include "video_core/renderer_opengl/pica_to_gl.h" | #include "video_core/renderer_opengl/pica_to_gl.h" | ||||||
| 
 | 
 | ||||||
| RasterizerCacheOpenGL::~RasterizerCacheOpenGL() { | RasterizerCacheOpenGL::~RasterizerCacheOpenGL() { | ||||||
|     FullFlush(); |     InvalidateAll(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| MICROPROFILE_DEFINE(OpenGL_TextureUpload, "OpenGL", "Texture Upload", MP_RGB(128, 64, 192)); | 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) { | void RasterizerCacheOpenGL::InvalidateInRange(PAddr addr, u32 size, bool ignore_hash) { | ||||||
|     // Flush any texture that falls in the flushed region
 |  | ||||||
|     // TODO: Optimize by also inserting upper bound (addr + size) of each texture into the same map and also narrow using lower_bound
 |     // 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); |     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(); |     texture_cache.clear(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -23,11 +23,11 @@ public: | ||||||
|         LoadAndBindTexture(state, texture_unit, Pica::DebugUtils::TextureInfo::FromPicaRegister(config.config, config.format)); |         LoadAndBindTexture(state, texture_unit, Pica::DebugUtils::TextureInfo::FromPicaRegister(config.config, config.format)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Flush any cached resource that touches the flushed region
 |     /// Invalidate any cached resource intersecting the specified region.
 | ||||||
|     void NotifyFlush(PAddr addr, u32 size, bool ignore_hash = false); |     void InvalidateInRange(PAddr addr, u32 size, bool ignore_hash = false); | ||||||
| 
 | 
 | ||||||
|     /// Flush all cached OpenGL resources tracked by this cache manager
 |     /// Invalidate all cached OpenGL resources tracked by this cache manager
 | ||||||
|     void FullFlush(); |     void InvalidateAll(); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     struct CachedTexture { |     struct CachedTexture { | ||||||
|  |  | ||||||
|  | @ -93,7 +93,6 @@ static std::array<GLfloat, 3*2> MakeOrthographicMatrix(const float width, const | ||||||
| 
 | 
 | ||||||
| /// RendererOpenGL constructor
 | /// RendererOpenGL constructor
 | ||||||
| RendererOpenGL::RendererOpenGL() { | RendererOpenGL::RendererOpenGL() { | ||||||
|     hw_rasterizer.reset(new RasterizerOpenGL()); |  | ||||||
|     resolution_width  = std::max(VideoCore::kScreenTopWidth, VideoCore::kScreenBottomWidth); |     resolution_width  = std::max(VideoCore::kScreenTopWidth, VideoCore::kScreenBottomWidth); | ||||||
|     resolution_height = VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight; |     resolution_height = VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight; | ||||||
| } | } | ||||||
|  | @ -157,15 +156,7 @@ void RendererOpenGL::SwapBuffers() { | ||||||
| 
 | 
 | ||||||
|     profiler.BeginFrame(); |     profiler.BeginFrame(); | ||||||
| 
 | 
 | ||||||
|     bool hw_renderer_enabled = VideoCore::g_hw_renderer_enabled; |     RefreshRasterizerSetting(); | ||||||
|     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(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     if (Pica::g_debug_context && Pica::g_debug_context->recorder) { |     if (Pica::g_debug_context && Pica::g_debug_context->recorder) { | ||||||
|         Pica::g_debug_context->recorder->FrameFinished(); |         Pica::g_debug_context->recorder->FrameFinished(); | ||||||
|  | @ -286,8 +277,6 @@ void RendererOpenGL::InitOpenGLObjects() { | ||||||
| 
 | 
 | ||||||
|     state.texture_units[0].texture_2d = 0; |     state.texture_units[0].texture_2d = 0; | ||||||
|     state.Apply(); |     state.Apply(); | ||||||
| 
 |  | ||||||
|     hw_rasterizer->InitObjects(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, | 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_VENDOR: %s", glGetString(GL_VENDOR)); | ||||||
|     LOG_INFO(Render_OpenGL, "GL_RENDERER: %s", glGetString(GL_RENDERER)); |     LOG_INFO(Render_OpenGL, "GL_RENDERER: %s", glGetString(GL_RENDERER)); | ||||||
|     InitOpenGLObjects(); |     InitOpenGLObjects(); | ||||||
|  | 
 | ||||||
|  |     RefreshRasterizerSetting(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Shutdown the renderer
 | /// Shutdown the renderer
 | ||||||
|  |  | ||||||
							
								
								
									
										16
									
								
								src/video_core/swrasterizer.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/video_core/swrasterizer.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -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); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										26
									
								
								src/video_core/swrasterizer.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/video_core/swrasterizer.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 {} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue