diff options
Diffstat (limited to 'src/video_core/gpu.cpp')
-rw-r--r-- | src/video_core/gpu.cpp | 98 |
1 files changed, 69 insertions, 29 deletions
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 52706505b..2c47541cb 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -17,26 +17,15 @@ namespace Tegra { -u32 FramebufferConfig::BytesPerPixel(PixelFormat format) { - switch (format) { - case PixelFormat::ABGR8: - case PixelFormat::BGRA8: - return 4; - default: - return 4; - } - - UNREACHABLE(); -} - -GPU::GPU(Core::System& system, VideoCore::RendererBase& renderer) : renderer{renderer} { +GPU::GPU(Core::System& system, VideoCore::RendererBase& renderer, bool is_async) + : system{system}, renderer{renderer}, is_async{is_async} { auto& rasterizer{renderer.Rasterizer()}; - memory_manager = std::make_unique<Tegra::MemoryManager>(rasterizer); + memory_manager = std::make_unique<Tegra::MemoryManager>(system, rasterizer); dma_pusher = std::make_unique<Tegra::DmaPusher>(*this); maxwell_3d = std::make_unique<Engines::Maxwell3D>(system, rasterizer, *memory_manager); - fermi_2d = std::make_unique<Engines::Fermi2D>(rasterizer, *memory_manager); + fermi_2d = std::make_unique<Engines::Fermi2D>(rasterizer); kepler_compute = std::make_unique<Engines::KeplerCompute>(system, rasterizer, *memory_manager); - maxwell_dma = std::make_unique<Engines::MaxwellDMA>(system, rasterizer, *memory_manager); + maxwell_dma = std::make_unique<Engines::MaxwellDMA>(system, *memory_manager); kepler_memory = std::make_unique<Engines::KeplerMemory>(system, *memory_manager); } @@ -50,6 +39,14 @@ const Engines::Maxwell3D& GPU::Maxwell3D() const { return *maxwell_3d; } +Engines::KeplerCompute& GPU::KeplerCompute() { + return *kepler_compute; +} + +const Engines::KeplerCompute& GPU::KeplerCompute() const { + return *kepler_compute; +} + MemoryManager& GPU::MemoryManager() { return *memory_manager; } @@ -66,6 +63,55 @@ const DmaPusher& GPU::DmaPusher() const { return *dma_pusher; } +void GPU::IncrementSyncPoint(const u32 syncpoint_id) { + syncpoints[syncpoint_id]++; + std::lock_guard lock{sync_mutex}; + if (!syncpt_interrupts[syncpoint_id].empty()) { + u32 value = syncpoints[syncpoint_id].load(); + auto it = syncpt_interrupts[syncpoint_id].begin(); + while (it != syncpt_interrupts[syncpoint_id].end()) { + if (value >= *it) { + TriggerCpuInterrupt(syncpoint_id, *it); + it = syncpt_interrupts[syncpoint_id].erase(it); + continue; + } + it++; + } + } +} + +u32 GPU::GetSyncpointValue(const u32 syncpoint_id) const { + return syncpoints[syncpoint_id].load(); +} + +void GPU::RegisterSyncptInterrupt(const u32 syncpoint_id, const u32 value) { + auto& interrupt = syncpt_interrupts[syncpoint_id]; + bool contains = std::any_of(interrupt.begin(), interrupt.end(), + [value](u32 in_value) { return in_value == value; }); + if (contains) { + return; + } + syncpt_interrupts[syncpoint_id].emplace_back(value); +} + +bool GPU::CancelSyncptInterrupt(const u32 syncpoint_id, const u32 value) { + std::lock_guard lock{sync_mutex}; + auto& interrupt = syncpt_interrupts[syncpoint_id]; + const auto iter = + std::find_if(interrupt.begin(), interrupt.end(), + [value](u32 interrupt_value) { return value == interrupt_value; }); + + if (iter == interrupt.end()) { + return false; + } + interrupt.erase(iter); + return true; +} + +void GPU::FlushCommands() { + renderer.Rasterizer().FlushCommands(); +} + u32 RenderTargetBytesPerPixel(RenderTargetFormat format) { ASSERT(format != RenderTargetFormat::NONE); @@ -143,12 +189,12 @@ enum class BufferMethods { NotifyIntr = 0x8, WrcacheFlush = 0x9, Unk28 = 0xA, - Unk2c = 0xB, + UnkCacheFlush = 0xB, RefCnt = 0x14, SemaphoreAcquire = 0x1A, SemaphoreRelease = 0x1B, - Unk70 = 0x1C, - Unk74 = 0x1D, + FenceValue = 0x1C, + FenceAction = 0x1D, Unk78 = 0x1E, Unk7c = 0x1F, Yield = 0x20, @@ -194,6 +240,10 @@ void GPU::CallPullerMethod(const MethodCall& method_call) { case BufferMethods::SemaphoreAddressLow: case BufferMethods::SemaphoreSequence: case BufferMethods::RefCnt: + case BufferMethods::UnkCacheFlush: + case BufferMethods::WrcacheFlush: + case BufferMethods::FenceValue: + case BufferMethods::FenceAction: break; case BufferMethods::SemaphoreTrigger: { ProcessSemaphoreTriggerMethod(); @@ -204,21 +254,11 @@ void GPU::CallPullerMethod(const MethodCall& method_call) { LOG_ERROR(HW_GPU, "Special puller engine method NotifyIntr not implemented"); break; } - case BufferMethods::WrcacheFlush: { - // TODO(Kmather73): Research and implement this method. - LOG_ERROR(HW_GPU, "Special puller engine method WrcacheFlush not implemented"); - break; - } case BufferMethods::Unk28: { // TODO(Kmather73): Research and implement this method. LOG_ERROR(HW_GPU, "Special puller engine method Unk28 not implemented"); break; } - case BufferMethods::Unk2c: { - // TODO(Kmather73): Research and implement this method. - LOG_ERROR(HW_GPU, "Special puller engine method Unk2c not implemented"); - break; - } case BufferMethods::SemaphoreAcquire: { ProcessSemaphoreAcquire(); break; |