mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	Merge pull request #1271 from Subv/kepler_engine
GPU: Basic implementation of the Kepler Inline Memory engine (p2mf).
This commit is contained in:
		
						commit
						daee15b058
					
				| @ -5,6 +5,8 @@ add_library(video_core STATIC | |||||||
|     debug_utils/debug_utils.h |     debug_utils/debug_utils.h | ||||||
|     engines/fermi_2d.cpp |     engines/fermi_2d.cpp | ||||||
|     engines/fermi_2d.h |     engines/fermi_2d.h | ||||||
|  |     engines/kepler_memory.cpp | ||||||
|  |     engines/kepler_memory.h | ||||||
|     engines/maxwell_3d.cpp |     engines/maxwell_3d.cpp | ||||||
|     engines/maxwell_3d.h |     engines/maxwell_3d.h | ||||||
|     engines/maxwell_compute.cpp |     engines/maxwell_compute.cpp | ||||||
|  | |||||||
| @ -14,6 +14,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/engines/fermi_2d.h" | #include "video_core/engines/fermi_2d.h" | ||||||
|  | #include "video_core/engines/kepler_memory.h" | ||||||
| #include "video_core/engines/maxwell_3d.h" | #include "video_core/engines/maxwell_3d.h" | ||||||
| #include "video_core/engines/maxwell_compute.h" | #include "video_core/engines/maxwell_compute.h" | ||||||
| #include "video_core/engines/maxwell_dma.h" | #include "video_core/engines/maxwell_dma.h" | ||||||
| @ -69,6 +70,9 @@ void GPU::ProcessCommandLists(const std::vector<CommandListHeader>& commands) { | |||||||
|         case EngineID::MAXWELL_DMA_COPY_A: |         case EngineID::MAXWELL_DMA_COPY_A: | ||||||
|             maxwell_dma->WriteReg(method, value); |             maxwell_dma->WriteReg(method, value); | ||||||
|             break; |             break; | ||||||
|  |         case EngineID::KEPLER_INLINE_TO_MEMORY_B: | ||||||
|  |             kepler_memory->WriteReg(method, value); | ||||||
|  |             break; | ||||||
|         default: |         default: | ||||||
|             UNIMPLEMENTED_MSG("Unimplemented engine"); |             UNIMPLEMENTED_MSG("Unimplemented engine"); | ||||||
|         } |         } | ||||||
|  | |||||||
							
								
								
									
										45
									
								
								src/video_core/engines/kepler_memory.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/video_core/engines/kepler_memory.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | // Copyright 2018 yuzu Emulator Project
 | ||||||
|  | // Licensed under GPLv2 or any later version
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #include "common/logging/log.h" | ||||||
|  | #include "core/memory.h" | ||||||
|  | #include "video_core/engines/kepler_memory.h" | ||||||
|  | 
 | ||||||
|  | namespace Tegra::Engines { | ||||||
|  | 
 | ||||||
|  | KeplerMemory::KeplerMemory(MemoryManager& memory_manager) : memory_manager(memory_manager) {} | ||||||
|  | KeplerMemory::~KeplerMemory() = default; | ||||||
|  | 
 | ||||||
|  | void KeplerMemory::WriteReg(u32 method, u32 value) { | ||||||
|  |     ASSERT_MSG(method < Regs::NUM_REGS, | ||||||
|  |                "Invalid KeplerMemory register, increase the size of the Regs structure"); | ||||||
|  | 
 | ||||||
|  |     regs.reg_array[method] = value; | ||||||
|  | 
 | ||||||
|  |     switch (method) { | ||||||
|  |     case KEPLERMEMORY_REG_INDEX(exec): { | ||||||
|  |         state.write_offset = 0; | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  |     case KEPLERMEMORY_REG_INDEX(data): { | ||||||
|  |         ProcessData(value); | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void KeplerMemory::ProcessData(u32 data) { | ||||||
|  |     ASSERT_MSG(regs.exec.linear, "Non-linear uploads are not supported"); | ||||||
|  |     ASSERT(regs.dest.x == 0 && regs.dest.y == 0 && regs.dest.z == 0); | ||||||
|  | 
 | ||||||
|  |     GPUVAddr address = regs.dest.Address(); | ||||||
|  |     VAddr dest_address = | ||||||
|  |         *memory_manager.GpuToCpuAddress(address + state.write_offset * sizeof(u32)); | ||||||
|  | 
 | ||||||
|  |     Memory::Write32(dest_address, data); | ||||||
|  | 
 | ||||||
|  |     state.write_offset++; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace Tegra::Engines
 | ||||||
							
								
								
									
										90
									
								
								src/video_core/engines/kepler_memory.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/video_core/engines/kepler_memory.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,90 @@ | |||||||
|  | // Copyright 2018 yuzu Emulator Project
 | ||||||
|  | // Licensed under GPLv2 or any later version
 | ||||||
|  | // Refer to the license.txt file included.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <array> | ||||||
|  | #include "common/assert.h" | ||||||
|  | #include "common/bit_field.h" | ||||||
|  | #include "common/common_funcs.h" | ||||||
|  | #include "common/common_types.h" | ||||||
|  | #include "video_core/memory_manager.h" | ||||||
|  | 
 | ||||||
|  | namespace Tegra::Engines { | ||||||
|  | 
 | ||||||
|  | #define KEPLERMEMORY_REG_INDEX(field_name)                                                         \ | ||||||
|  |     (offsetof(Tegra::Engines::KeplerMemory::Regs, field_name) / sizeof(u32)) | ||||||
|  | 
 | ||||||
|  | class KeplerMemory final { | ||||||
|  | public: | ||||||
|  |     KeplerMemory(MemoryManager& memory_manager); | ||||||
|  |     ~KeplerMemory(); | ||||||
|  | 
 | ||||||
|  |     /// Write the value to the register identified by method.
 | ||||||
|  |     void WriteReg(u32 method, u32 value); | ||||||
|  | 
 | ||||||
|  |     struct Regs { | ||||||
|  |         static constexpr size_t NUM_REGS = 0x7F; | ||||||
|  | 
 | ||||||
|  |         union { | ||||||
|  |             struct { | ||||||
|  |                 INSERT_PADDING_WORDS(0x60); | ||||||
|  | 
 | ||||||
|  |                 u32 line_length_in; | ||||||
|  |                 u32 line_count; | ||||||
|  | 
 | ||||||
|  |                 struct { | ||||||
|  |                     u32 address_high; | ||||||
|  |                     u32 address_low; | ||||||
|  |                     u32 pitch; | ||||||
|  |                     u32 block_dimensions; | ||||||
|  |                     u32 width; | ||||||
|  |                     u32 height; | ||||||
|  |                     u32 depth; | ||||||
|  |                     u32 z; | ||||||
|  |                     u32 x; | ||||||
|  |                     u32 y; | ||||||
|  | 
 | ||||||
|  |                     GPUVAddr Address() const { | ||||||
|  |                         return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | | ||||||
|  |                                                      address_low); | ||||||
|  |                     } | ||||||
|  |                 } dest; | ||||||
|  | 
 | ||||||
|  |                 struct { | ||||||
|  |                     union { | ||||||
|  |                         BitField<0, 1, u32> linear; | ||||||
|  |                     }; | ||||||
|  |                 } exec; | ||||||
|  | 
 | ||||||
|  |                 u32 data; | ||||||
|  | 
 | ||||||
|  |                 INSERT_PADDING_WORDS(0x11); | ||||||
|  |             }; | ||||||
|  |             std::array<u32, NUM_REGS> reg_array; | ||||||
|  |         }; | ||||||
|  |     } regs{}; | ||||||
|  | 
 | ||||||
|  |     struct { | ||||||
|  |         u32 write_offset = 0; | ||||||
|  |     } state{}; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     MemoryManager& memory_manager; | ||||||
|  | 
 | ||||||
|  |     void ProcessData(u32 data); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #define ASSERT_REG_POSITION(field_name, position)                                                  \ | ||||||
|  |     static_assert(offsetof(KeplerMemory::Regs, field_name) == position * 4,                        \ | ||||||
|  |                   "Field " #field_name " has invalid position") | ||||||
|  | 
 | ||||||
|  | ASSERT_REG_POSITION(line_length_in, 0x60); | ||||||
|  | ASSERT_REG_POSITION(line_count, 0x61); | ||||||
|  | ASSERT_REG_POSITION(dest, 0x62); | ||||||
|  | ASSERT_REG_POSITION(exec, 0x6C); | ||||||
|  | ASSERT_REG_POSITION(data, 0x6D); | ||||||
|  | #undef ASSERT_REG_POSITION | ||||||
|  | 
 | ||||||
|  | } // namespace Tegra::Engines
 | ||||||
| @ -4,6 +4,7 @@ | |||||||
| 
 | 
 | ||||||
| #include "common/assert.h" | #include "common/assert.h" | ||||||
| #include "video_core/engines/fermi_2d.h" | #include "video_core/engines/fermi_2d.h" | ||||||
|  | #include "video_core/engines/kepler_memory.h" | ||||||
| #include "video_core/engines/maxwell_3d.h" | #include "video_core/engines/maxwell_3d.h" | ||||||
| #include "video_core/engines/maxwell_compute.h" | #include "video_core/engines/maxwell_compute.h" | ||||||
| #include "video_core/engines/maxwell_dma.h" | #include "video_core/engines/maxwell_dma.h" | ||||||
| @ -27,6 +28,7 @@ GPU::GPU(VideoCore::RasterizerInterface& rasterizer) { | |||||||
|     fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager); |     fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager); | ||||||
|     maxwell_compute = std::make_unique<Engines::MaxwellCompute>(); |     maxwell_compute = std::make_unique<Engines::MaxwellCompute>(); | ||||||
|     maxwell_dma = std::make_unique<Engines::MaxwellDMA>(*memory_manager); |     maxwell_dma = std::make_unique<Engines::MaxwellDMA>(*memory_manager); | ||||||
|  |     kepler_memory = std::make_unique<Engines::KeplerMemory>(*memory_manager); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| GPU::~GPU() = default; | GPU::~GPU() = default; | ||||||
|  | |||||||
| @ -102,6 +102,7 @@ class Fermi2D; | |||||||
| class Maxwell3D; | class Maxwell3D; | ||||||
| class MaxwellCompute; | class MaxwellCompute; | ||||||
| class MaxwellDMA; | class MaxwellDMA; | ||||||
|  | class KeplerMemory; | ||||||
| } // namespace Engines
 | } // namespace Engines
 | ||||||
| 
 | 
 | ||||||
| enum class EngineID { | enum class EngineID { | ||||||
| @ -146,6 +147,8 @@ private: | |||||||
|     std::unique_ptr<Engines::MaxwellCompute> maxwell_compute; |     std::unique_ptr<Engines::MaxwellCompute> maxwell_compute; | ||||||
|     /// DMA engine
 |     /// DMA engine
 | ||||||
|     std::unique_ptr<Engines::MaxwellDMA> maxwell_dma; |     std::unique_ptr<Engines::MaxwellDMA> maxwell_dma; | ||||||
|  |     /// Inline memory engine
 | ||||||
|  |     std::unique_ptr<Engines::KeplerMemory> kepler_memory; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace Tegra
 | } // namespace Tegra
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 bunnei
						bunnei