From 013778aa21bad3769b739d14843b8ef2bb3185c9 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 20 Apr 2018 15:52:06 -0500 Subject: Qt: Update the WaitTree widget to show info about the current mutex of each thread. --- src/yuzu/debugger/wait_tree.cpp | 86 ++++++++++++++++------------------------- src/yuzu/debugger/wait_tree.h | 43 +++++++-------------- 2 files changed, 47 insertions(+), 82 deletions(-) (limited to 'src/yuzu/debugger') diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index cae2864e5..acc4c2e0b 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -6,8 +6,8 @@ #include "yuzu/util/util.h" #include "core/core.h" -#include "core/hle/kernel/condition_variable.h" #include "core/hle/kernel/event.h" +#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/mutex.h" #include "core/hle/kernel/thread.h" #include "core/hle/kernel/timer.h" @@ -67,6 +67,29 @@ QString WaitTreeText::GetText() const { return text; } +WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address) : mutex_address(mutex_address) { + mutex_value = Memory::Read32(mutex_address); + owner_handle = static_cast(mutex_value & Kernel::Mutex::MutexOwnerMask); + owner = Kernel::g_handle_table.Get(owner_handle); +} + +QString WaitTreeMutexInfo::GetText() const { + return tr("waiting for mutex 0x%1").arg(mutex_address, 16, 16, QLatin1Char('0')); +} + +std::vector> WaitTreeMutexInfo::GetChildren() const { + std::vector> list; + + bool has_waiters = (mutex_value & Kernel::Mutex::MutexHasWaitersFlag) != 0; + + list.push_back(std::make_unique(tr("has waiters: %1").arg(has_waiters))); + list.push_back(std::make_unique( + tr("owner handle: 0x%1").arg(owner_handle, 8, 16, QLatin1Char('0')))); + if (owner != nullptr) + list.push_back(std::make_unique(*owner)); + return list; +} + WaitTreeWaitObject::WaitTreeWaitObject(const Kernel::WaitObject& o) : object(o) {} bool WaitTreeExpandableItem::IsExpandable() const { @@ -84,11 +107,6 @@ std::unique_ptr WaitTreeWaitObject::make(const Kernel::WaitO switch (object.GetHandleType()) { case Kernel::HandleType::Event: return std::make_unique(static_cast(object)); - case Kernel::HandleType::Mutex: - return std::make_unique(static_cast(object)); - case Kernel::HandleType::ConditionVariable: - return std::make_unique( - static_cast(object)); case Kernel::HandleType::Timer: return std::make_unique(static_cast(object)); case Kernel::HandleType::Thread: @@ -160,6 +178,9 @@ QString WaitTreeThread::GetText() const { case THREADSTATUS_WAIT_SYNCH_ANY: status = tr("waiting for objects"); break; + case THREADSTATUS_WAIT_MUTEX: + status = tr("waiting for mutex"); + break; case THREADSTATUS_DORMANT: status = tr("dormant"); break; @@ -186,6 +207,7 @@ QColor WaitTreeThread::GetColor() const { return QColor(Qt::GlobalColor::darkYellow); case THREADSTATUS_WAIT_SYNCH_ALL: case THREADSTATUS_WAIT_SYNCH_ANY: + case THREADSTATUS_WAIT_MUTEX: return QColor(Qt::GlobalColor::red); case THREADSTATUS_DORMANT: return QColor(Qt::GlobalColor::darkCyan); @@ -225,11 +247,11 @@ std::vector> WaitTreeThread::GetChildren() const { list.push_back(std::make_unique( tr("last running ticks = %1").arg(thread.last_running_ticks))); - if (thread.held_mutexes.empty()) { - list.push_back(std::make_unique(tr("not holding mutex"))); - } else { - list.push_back(std::make_unique(thread.held_mutexes)); - } + if (thread.mutex_wait_address != 0) + list.push_back(std::make_unique(thread.mutex_wait_address)); + else + list.push_back(std::make_unique(tr("not waiting for mutex"))); + if (thread.status == THREADSTATUS_WAIT_SYNCH_ANY || thread.status == THREADSTATUS_WAIT_SYNCH_ALL) { list.push_back(std::make_unique(thread.wait_objects, @@ -250,33 +272,6 @@ std::vector> WaitTreeEvent::GetChildren() const { return list; } -WaitTreeMutex::WaitTreeMutex(const Kernel::Mutex& object) : WaitTreeWaitObject(object) {} - -std::vector> WaitTreeMutex::GetChildren() const { - std::vector> list(WaitTreeWaitObject::GetChildren()); - - const auto& mutex = static_cast(object); - if (mutex.GetHasWaiters()) { - list.push_back(std::make_unique(tr("locked by thread:"))); - list.push_back(std::make_unique(*mutex.GetHoldingThread())); - } else { - list.push_back(std::make_unique(tr("free"))); - } - return list; -} - -WaitTreeConditionVariable::WaitTreeConditionVariable(const Kernel::ConditionVariable& object) - : WaitTreeWaitObject(object) {} - -std::vector> WaitTreeConditionVariable::GetChildren() const { - std::vector> list(WaitTreeWaitObject::GetChildren()); - - const auto& condition_variable = static_cast(object); - list.push_back(std::make_unique( - tr("available count = %1").arg(condition_variable.GetAvailableCount()))); - return list; -} - WaitTreeTimer::WaitTreeTimer(const Kernel::Timer& object) : WaitTreeWaitObject(object) {} std::vector> WaitTreeTimer::GetChildren() const { @@ -293,21 +288,6 @@ std::vector> WaitTreeTimer::GetChildren() const { return list; } -WaitTreeMutexList::WaitTreeMutexList( - const boost::container::flat_set>& list) - : mutex_list(list) {} - -QString WaitTreeMutexList::GetText() const { - return tr("holding mutexes"); -} - -std::vector> WaitTreeMutexList::GetChildren() const { - std::vector> list(mutex_list.size()); - std::transform(mutex_list.begin(), mutex_list.end(), list.begin(), - [](const auto& t) { return std::make_unique(*t); }); - return list; -} - WaitTreeThreadList::WaitTreeThreadList(const std::vector>& list) : thread_list(list) {} diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h index e538174eb..300ba9ae4 100644 --- a/src/yuzu/debugger/wait_tree.h +++ b/src/yuzu/debugger/wait_tree.h @@ -16,8 +16,6 @@ class EmuThread; namespace Kernel { class WaitObject; class Event; -class Mutex; -class ConditionVariable; class Thread; class Timer; } // namespace Kernel @@ -61,6 +59,20 @@ public: bool IsExpandable() const override; }; +class WaitTreeMutexInfo : public WaitTreeExpandableItem { + Q_OBJECT +public: + explicit WaitTreeMutexInfo(VAddr mutex_address); + QString GetText() const override; + std::vector> GetChildren() const override; + +private: + VAddr mutex_address; + u32 mutex_value; + Kernel::Handle owner_handle; + Kernel::SharedPtr owner; +}; + class WaitTreeWaitObject : public WaitTreeExpandableItem { Q_OBJECT public: @@ -104,20 +116,6 @@ public: std::vector> GetChildren() const override; }; -class WaitTreeMutex : public WaitTreeWaitObject { - Q_OBJECT -public: - explicit WaitTreeMutex(const Kernel::Mutex& object); - std::vector> GetChildren() const override; -}; - -class WaitTreeConditionVariable : public WaitTreeWaitObject { - Q_OBJECT -public: - explicit WaitTreeConditionVariable(const Kernel::ConditionVariable& object); - std::vector> GetChildren() const override; -}; - class WaitTreeTimer : public WaitTreeWaitObject { Q_OBJECT public: @@ -125,19 +123,6 @@ public: std::vector> GetChildren() const override; }; -class WaitTreeMutexList : public WaitTreeExpandableItem { - Q_OBJECT -public: - explicit WaitTreeMutexList( - const boost::container::flat_set>& list); - - QString GetText() const override; - std::vector> GetChildren() const override; - -private: - const boost::container::flat_set>& mutex_list; -}; - class WaitTreeThreadList : public WaitTreeExpandableItem { Q_OBJECT public: -- cgit v1.2.3 From 010227e1490c01484903d4e9cf9038e74906ec7c Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 23 Apr 2018 10:50:28 -0500 Subject: GPU: Implement the RGB10_A2 RenderTarget format, it will use the same format as the A2BGR10 texture format. --- src/video_core/renderer_opengl/gl_rasterizer_cache.h | 2 ++ src/yuzu/debugger/graphics/graphics_surface.cpp | 2 ++ 2 files changed, 4 insertions(+) (limited to 'src/yuzu/debugger') diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index e4cb3390f..bf0fabb29 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -106,6 +106,8 @@ struct SurfaceParams { switch (format) { case Tegra::RenderTargetFormat::RGBA8_UNORM: return PixelFormat::ABGR8; + case Tegra::RenderTargetFormat::RGB10_A2_UNORM: + return PixelFormat::A2B10G10R10; default: NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast(format)); UNREACHABLE(); diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp index 1e4844b57..5fada74be 100644 --- a/src/yuzu/debugger/graphics/graphics_surface.cpp +++ b/src/yuzu/debugger/graphics/graphics_surface.cpp @@ -25,6 +25,8 @@ static Tegra::Texture::TextureFormat ConvertToTextureFormat( switch (render_target_format) { case Tegra::RenderTargetFormat::RGBA8_UNORM: return Tegra::Texture::TextureFormat::A8R8G8B8; + case Tegra::RenderTargetFormat::RGB10_A2_UNORM: + return Tegra::Texture::TextureFormat::A2B10G10R10; default: UNIMPLEMENTED_MSG("Unimplemented RT format"); } -- cgit v1.2.3 From 9e11a76e926a7190880063d8fc8c3d97003b9938 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 21 Apr 2018 11:16:21 -0400 Subject: memory_manager: Use GPUVAdddr, not PAddr, for GPU addresses. --- src/video_core/command_processor.cpp | 4 +- src/video_core/engines/maxwell_3d.cpp | 11 ++-- src/video_core/memory_manager.cpp | 72 +++++++++++----------- src/video_core/memory_manager.h | 16 ++--- src/video_core/renderer_opengl/gl_rasterizer.cpp | 6 +- .../renderer_opengl/gl_rasterizer_cache.cpp | 4 +- src/yuzu/debugger/graphics/graphics_surface.cpp | 4 +- 7 files changed, 57 insertions(+), 60 deletions(-) (limited to 'src/yuzu/debugger') diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index d4cdb4ab2..7850ae103 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -90,9 +90,7 @@ void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) } void GPU::ProcessCommandList(GPUVAddr address, u32 size) { - // TODO(Subv): PhysicalToVirtualAddress is a misnomer, it converts a GPU VAddr into an - // application VAddr. - const VAddr head_address = memory_manager->PhysicalToVirtualAddress(address); + const VAddr head_address = memory_manager->GpuToCpuAddress(address); VAddr current_addr = head_address; while (current_addr < head_address + size * sizeof(CommandHeader)) { const CommandHeader header = {Memory::Read32(current_addr)}; diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 35773a695..8d7d627b8 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -145,7 +145,7 @@ void Maxwell3D::ProcessQueryGet() { GPUVAddr sequence_address = regs.query.QueryAddress(); // Since the sequence address is given as a GPU VAddr, we have to convert it to an application // VAddr before writing. - VAddr address = memory_manager.PhysicalToVirtualAddress(sequence_address); + VAddr address = memory_manager.GpuToCpuAddress(sequence_address); // TODO(Subv): Support the other query units. ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop, @@ -225,8 +225,7 @@ void Maxwell3D::ProcessCBData(u32 value) { // Don't allow writing past the end of the buffer. ASSERT(regs.const_buffer.cb_pos + sizeof(u32) <= regs.const_buffer.cb_size); - VAddr address = - memory_manager.PhysicalToVirtualAddress(buffer_address + regs.const_buffer.cb_pos); + VAddr address = memory_manager.GpuToCpuAddress(buffer_address + regs.const_buffer.cb_pos); Memory::Write32(address, value); @@ -238,7 +237,7 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { GPUVAddr tic_base_address = regs.tic.TICAddress(); GPUVAddr tic_address_gpu = tic_base_address + tic_index * sizeof(Texture::TICEntry); - VAddr tic_address_cpu = memory_manager.PhysicalToVirtualAddress(tic_address_gpu); + VAddr tic_address_cpu = memory_manager.GpuToCpuAddress(tic_address_gpu); Texture::TICEntry tic_entry; Memory::ReadBlock(tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry)); @@ -268,7 +267,7 @@ Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const { GPUVAddr tsc_base_address = regs.tsc.TSCAddress(); GPUVAddr tsc_address_gpu = tsc_base_address + tsc_index * sizeof(Texture::TSCEntry); - VAddr tsc_address_cpu = memory_manager.PhysicalToVirtualAddress(tsc_address_gpu); + VAddr tsc_address_cpu = memory_manager.GpuToCpuAddress(tsc_address_gpu); Texture::TSCEntry tsc_entry; Memory::ReadBlock(tsc_address_cpu, &tsc_entry, sizeof(Texture::TSCEntry)); @@ -293,7 +292,7 @@ std::vector Maxwell3D::GetStageTextures(Regs::ShaderSt current_texture < tex_info_buffer_end; current_texture += sizeof(Texture::TextureHandle)) { Texture::TextureHandle tex_handle{ - Memory::Read32(memory_manager.PhysicalToVirtualAddress(current_texture))}; + Memory::Read32(memory_manager.GpuToCpuAddress(current_texture))}; Texture::FullTextureInfo tex_info{}; // TODO(Subv): Use the shader to determine which textures are actually accessed. diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 2e1edee03..3f21071c0 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp @@ -8,90 +8,90 @@ namespace Tegra { -PAddr MemoryManager::AllocateSpace(u64 size, u64 align) { - boost::optional paddr = FindFreeBlock(size, align); - ASSERT(paddr); +GPUVAddr MemoryManager::AllocateSpace(u64 size, u64 align) { + boost::optional gpu_addr = FindFreeBlock(size, align); + ASSERT(gpu_addr); for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { - ASSERT(PageSlot(*paddr + offset) == static_cast(PageStatus::Unmapped)); - PageSlot(*paddr + offset) = static_cast(PageStatus::Allocated); + ASSERT(PageSlot(*gpu_addr + offset) == static_cast(PageStatus::Unmapped)); + PageSlot(*gpu_addr + offset) = static_cast(PageStatus::Allocated); } - return *paddr; + return *gpu_addr; } -PAddr MemoryManager::AllocateSpace(PAddr paddr, u64 size, u64 align) { +GPUVAddr MemoryManager::AllocateSpace(GPUVAddr gpu_addr, u64 size, u64 align) { for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { - ASSERT(PageSlot(paddr + offset) == static_cast(PageStatus::Unmapped)); - PageSlot(paddr + offset) = static_cast(PageStatus::Allocated); + ASSERT(PageSlot(gpu_addr + offset) == static_cast(PageStatus::Unmapped)); + PageSlot(gpu_addr + offset) = static_cast(PageStatus::Allocated); } - return paddr; + return gpu_addr; } -PAddr MemoryManager::MapBufferEx(VAddr vaddr, u64 size) { - boost::optional paddr = FindFreeBlock(size, PAGE_SIZE); - ASSERT(paddr); +GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, u64 size) { + boost::optional gpu_addr = FindFreeBlock(size, PAGE_SIZE); + ASSERT(gpu_addr); for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { - ASSERT(PageSlot(*paddr + offset) == static_cast(PageStatus::Unmapped)); - PageSlot(*paddr + offset) = vaddr + offset; + ASSERT(PageSlot(*gpu_addr + offset) == static_cast(PageStatus::Unmapped)); + PageSlot(*gpu_addr + offset) = cpu_addr + offset; } - return *paddr; + return *gpu_addr; } -PAddr MemoryManager::MapBufferEx(VAddr vaddr, PAddr paddr, u64 size) { - ASSERT((paddr & PAGE_MASK) == 0); +GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size) { + ASSERT((gpu_addr & PAGE_MASK) == 0); for (u64 offset = 0; offset < size; offset += PAGE_SIZE) { - ASSERT(PageSlot(paddr + offset) == static_cast(PageStatus::Allocated)); - PageSlot(paddr + offset) = vaddr + offset; + ASSERT(PageSlot(gpu_addr + offset) == static_cast(PageStatus::Allocated)); + PageSlot(gpu_addr + offset) = cpu_addr + offset; } - return paddr; + return gpu_addr; } -boost::optional MemoryManager::FindFreeBlock(u64 size, u64 align) { - PAddr paddr = 0; +boost::optional MemoryManager::FindFreeBlock(u64 size, u64 align) { + GPUVAddr gpu_addr = 0; u64 free_space = 0; align = (align + PAGE_MASK) & ~PAGE_MASK; - while (paddr + free_space < MAX_ADDRESS) { - if (!IsPageMapped(paddr + free_space)) { + while (gpu_addr + free_space < MAX_ADDRESS) { + if (!IsPageMapped(gpu_addr + free_space)) { free_space += PAGE_SIZE; if (free_space >= size) { - return paddr; + return gpu_addr; } } else { - paddr += free_space + PAGE_SIZE; + gpu_addr += free_space + PAGE_SIZE; free_space = 0; - paddr = Common::AlignUp(paddr, align); + gpu_addr = Common::AlignUp(gpu_addr, align); } } return {}; } -VAddr MemoryManager::PhysicalToVirtualAddress(PAddr paddr) { - VAddr base_addr = PageSlot(paddr); +VAddr MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) { + VAddr base_addr = PageSlot(gpu_addr); ASSERT(base_addr != static_cast(PageStatus::Unmapped)); - return base_addr + (paddr & PAGE_MASK); + return base_addr + (gpu_addr & PAGE_MASK); } -bool MemoryManager::IsPageMapped(PAddr paddr) { - return PageSlot(paddr) != static_cast(PageStatus::Unmapped); +bool MemoryManager::IsPageMapped(GPUVAddr gpu_addr) { + return PageSlot(gpu_addr) != static_cast(PageStatus::Unmapped); } -VAddr& MemoryManager::PageSlot(PAddr paddr) { - auto& block = page_table[(paddr >> (PAGE_BITS + PAGE_TABLE_BITS)) & PAGE_TABLE_MASK]; +VAddr& MemoryManager::PageSlot(GPUVAddr gpu_addr) { + auto& block = page_table[(gpu_addr >> (PAGE_BITS + PAGE_TABLE_BITS)) & PAGE_TABLE_MASK]; if (!block) { block = std::make_unique(); for (unsigned index = 0; index < PAGE_BLOCK_SIZE; index++) { (*block)[index] = static_cast(PageStatus::Unmapped); } } - return (*block)[(paddr >> PAGE_BITS) & PAGE_BLOCK_MASK]; + return (*block)[(gpu_addr >> PAGE_BITS) & PAGE_BLOCK_MASK]; } } // namespace Tegra diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h index b73e283f8..4710cb21f 100644 --- a/src/video_core/memory_manager.h +++ b/src/video_core/memory_manager.h @@ -18,20 +18,20 @@ class MemoryManager final { public: MemoryManager() = default; - PAddr AllocateSpace(u64 size, u64 align); - PAddr AllocateSpace(PAddr paddr, u64 size, u64 align); - PAddr MapBufferEx(VAddr vaddr, u64 size); - PAddr MapBufferEx(VAddr vaddr, PAddr paddr, u64 size); - VAddr PhysicalToVirtualAddress(PAddr paddr); + GPUVAddr AllocateSpace(u64 size, u64 align); + GPUVAddr AllocateSpace(GPUVAddr gpu_addr, u64 size, u64 align); + GPUVAddr MapBufferEx(VAddr cpu_addr, u64 size); + GPUVAddr MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size); + VAddr GpuToCpuAddress(GPUVAddr gpu_addr); static constexpr u64 PAGE_BITS = 16; static constexpr u64 PAGE_SIZE = 1 << PAGE_BITS; static constexpr u64 PAGE_MASK = PAGE_SIZE - 1; private: - boost::optional FindFreeBlock(u64 size, u64 align = 1); - bool IsPageMapped(PAddr paddr); - VAddr& PageSlot(PAddr paddr); + boost::optional FindFreeBlock(u64 size, u64 align = 1); + bool IsPageMapped(GPUVAddr gpu_addr); + VAddr& PageSlot(GPUVAddr gpu_addr); enum class PageStatus : u64 { Unmapped = 0xFFFFFFFFFFFFFFFFULL, diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 82001e7b4..8568d6762 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -233,7 +233,7 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { // Fetch program code from memory GLShader::ProgramCode program_code; const u64 gpu_address{gpu.regs.code_address.CodeAddress() + shader_config.offset}; - const VAddr cpu_address{gpu.memory_manager.PhysicalToVirtualAddress(gpu_address)}; + const VAddr cpu_address{gpu.memory_manager.GpuToCpuAddress(gpu_address)}; Memory::ReadBlock(cpu_address, program_code.data(), program_code.size() * sizeof(u64)); GLShader::ShaderSetup setup{std::move(program_code)}; @@ -395,7 +395,7 @@ void RasterizerOpenGL::DrawArrays() { if (is_indexed) { const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager; const VAddr index_data_addr{ - memory_manager->PhysicalToVirtualAddress(regs.index_array.StartAddress())}; + memory_manager->GpuToCpuAddress(regs.index_array.StartAddress())}; Memory::ReadBlock(index_data_addr, offseted_buffer, index_buffer_size); index_buffer_offset = buffer_offset; @@ -659,7 +659,7 @@ u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, GLuint progr buffer_draw_state.enabled = true; buffer_draw_state.bindpoint = current_bindpoint + bindpoint; - VAddr addr = gpu.memory_manager->PhysicalToVirtualAddress(buffer.address); + VAddr addr = gpu.memory_manager->GpuToCpuAddress(buffer.address); std::vector data(used_buffer.GetSize() * sizeof(float)); Memory::ReadBlock(addr, data.data(), data.size()); diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 7410471cc..46f0f25aa 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -1028,7 +1028,7 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu auto& gpu = Core::System::GetInstance().GPU(); SurfaceParams params; - params.addr = gpu.memory_manager->PhysicalToVirtualAddress(config.tic.Address()); + params.addr = gpu.memory_manager->GpuToCpuAddress(config.tic.Address()); params.width = config.tic.Width(); params.height = config.tic.Height(); params.is_tiled = config.tic.IsTiled(); @@ -1106,7 +1106,7 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( color_params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight; SurfaceParams depth_params = color_params; - color_params.addr = memory_manager->PhysicalToVirtualAddress(config.Address()); + color_params.addr = memory_manager->GpuToCpuAddress(config.Address()); color_params.pixel_format = SurfaceParams::PixelFormatFromRenderTargetFormat(config.format); color_params.component_type = SurfaceParams::ComponentTypeFromRenderTarget(config.format); color_params.UpdateParams(); diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp index 5fada74be..5cadb807e 100644 --- a/src/yuzu/debugger/graphics/graphics_surface.cpp +++ b/src/yuzu/debugger/graphics/graphics_surface.cpp @@ -378,7 +378,7 @@ void GraphicsSurfaceWidget::OnUpdate() { // TODO: Implement a good way to visualize alpha components! QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32); - VAddr address = gpu.memory_manager->PhysicalToVirtualAddress(surface_address); + VAddr address = gpu.memory_manager->GpuToCpuAddress(surface_address); auto unswizzled_data = Tegra::Texture::UnswizzleTexture(address, surface_format, surface_width, surface_height); @@ -437,7 +437,7 @@ void GraphicsSurfaceWidget::SaveSurface() { pixmap->save(&file, "PNG"); } else if (selectedFilter == bin_filter) { auto& gpu = Core::System::GetInstance().GPU(); - VAddr address = gpu.memory_manager->PhysicalToVirtualAddress(surface_address); + VAddr address = gpu.memory_manager->GpuToCpuAddress(surface_address); const u8* buffer = Memory::GetPointer(address); ASSERT_MSG(buffer != nullptr, "Memory not accessible"); -- cgit v1.2.3 From 239ac8abe228b9080741ba7d50d9e13cc4a1ceae Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 21 Apr 2018 12:31:30 -0400 Subject: memory_manager: Make GpuToCpuAddress return an optional. --- src/video_core/command_processor.cpp | 6 +++--- src/video_core/engines/maxwell_3d.cpp | 21 +++++++++++---------- src/video_core/memory_manager.cpp | 7 ++++++- src/video_core/memory_manager.h | 5 ++++- src/video_core/renderer_opengl/gl_rasterizer.cpp | 14 +++++++------- .../renderer_opengl/gl_rasterizer_cache.cpp | 4 ++-- src/yuzu/debugger/graphics/graphics_surface.cpp | 8 ++++---- 7 files changed, 37 insertions(+), 28 deletions(-) (limited to 'src/yuzu/debugger') diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 7850ae103..2c04daba3 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -90,9 +90,9 @@ void GPU::WriteReg(u32 method, u32 subchannel, u32 value, u32 remaining_params) } void GPU::ProcessCommandList(GPUVAddr address, u32 size) { - const VAddr head_address = memory_manager->GpuToCpuAddress(address); - VAddr current_addr = head_address; - while (current_addr < head_address + size * sizeof(CommandHeader)) { + const boost::optional head_address = memory_manager->GpuToCpuAddress(address); + VAddr current_addr = *head_address; + while (current_addr < *head_address + size * sizeof(CommandHeader)) { const CommandHeader header = {Memory::Read32(current_addr)}; current_addr += sizeof(u32); diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 8d7d627b8..4e9aed380 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -145,7 +145,7 @@ void Maxwell3D::ProcessQueryGet() { GPUVAddr sequence_address = regs.query.QueryAddress(); // Since the sequence address is given as a GPU VAddr, we have to convert it to an application // VAddr before writing. - VAddr address = memory_manager.GpuToCpuAddress(sequence_address); + boost::optional address = memory_manager.GpuToCpuAddress(sequence_address); // TODO(Subv): Support the other query units. ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop, @@ -153,7 +153,7 @@ void Maxwell3D::ProcessQueryGet() { ASSERT_MSG(regs.query.query_get.short_query, "Writing the entire query result structure is unimplemented"); - u32 value = Memory::Read32(address); + u32 value = Memory::Read32(*address); u32 result = 0; // TODO(Subv): Support the other query variables @@ -173,7 +173,7 @@ void Maxwell3D::ProcessQueryGet() { case Regs::QueryMode::Write2: { // Write the current query sequence to the sequence address. u32 sequence = regs.query.query_sequence; - Memory::Write32(address, sequence); + Memory::Write32(*address, sequence); // TODO(Subv): Write the proper query response structure to the address when not using short // mode. @@ -225,9 +225,10 @@ void Maxwell3D::ProcessCBData(u32 value) { // Don't allow writing past the end of the buffer. ASSERT(regs.const_buffer.cb_pos + sizeof(u32) <= regs.const_buffer.cb_size); - VAddr address = memory_manager.GpuToCpuAddress(buffer_address + regs.const_buffer.cb_pos); + boost::optional address = + memory_manager.GpuToCpuAddress(buffer_address + regs.const_buffer.cb_pos); - Memory::Write32(address, value); + Memory::Write32(*address, value); // Increment the current buffer position. regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4; @@ -237,10 +238,10 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { GPUVAddr tic_base_address = regs.tic.TICAddress(); GPUVAddr tic_address_gpu = tic_base_address + tic_index * sizeof(Texture::TICEntry); - VAddr tic_address_cpu = memory_manager.GpuToCpuAddress(tic_address_gpu); + boost::optional tic_address_cpu = memory_manager.GpuToCpuAddress(tic_address_gpu); Texture::TICEntry tic_entry; - Memory::ReadBlock(tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry)); + Memory::ReadBlock(*tic_address_cpu, &tic_entry, sizeof(Texture::TICEntry)); ASSERT_MSG(tic_entry.header_version == Texture::TICHeaderVersion::BlockLinear || tic_entry.header_version == Texture::TICHeaderVersion::Pitch, @@ -267,10 +268,10 @@ Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const { GPUVAddr tsc_base_address = regs.tsc.TSCAddress(); GPUVAddr tsc_address_gpu = tsc_base_address + tsc_index * sizeof(Texture::TSCEntry); - VAddr tsc_address_cpu = memory_manager.GpuToCpuAddress(tsc_address_gpu); + boost::optional tsc_address_cpu = memory_manager.GpuToCpuAddress(tsc_address_gpu); Texture::TSCEntry tsc_entry; - Memory::ReadBlock(tsc_address_cpu, &tsc_entry, sizeof(Texture::TSCEntry)); + Memory::ReadBlock(*tsc_address_cpu, &tsc_entry, sizeof(Texture::TSCEntry)); return tsc_entry; } @@ -292,7 +293,7 @@ std::vector Maxwell3D::GetStageTextures(Regs::ShaderSt current_texture < tex_info_buffer_end; current_texture += sizeof(Texture::TextureHandle)) { Texture::TextureHandle tex_handle{ - Memory::Read32(memory_manager.GpuToCpuAddress(current_texture))}; + Memory::Read32(*memory_manager.GpuToCpuAddress(current_texture))}; Texture::FullTextureInfo tex_info{}; // TODO(Subv): Use the shader to determine which textures are actually accessed. diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 3f21071c0..9bbbb7e65 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp @@ -73,9 +73,14 @@ boost::optional MemoryManager::FindFreeBlock(u64 size, u64 align) { return {}; } -VAddr MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) { +boost::optional MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) { VAddr base_addr = PageSlot(gpu_addr); ASSERT(base_addr != static_cast(PageStatus::Unmapped)); + + if (base_addr == static_cast(PageStatus::Allocated)) { + return {}; + } + return base_addr + (gpu_addr & PAGE_MASK); } diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h index 4710cb21f..246c8fb7e 100644 --- a/src/video_core/memory_manager.h +++ b/src/video_core/memory_manager.h @@ -6,6 +6,9 @@ #include #include + +#include + #include "common/common_types.h" #include "core/memory.h" @@ -22,7 +25,7 @@ public: GPUVAddr AllocateSpace(GPUVAddr gpu_addr, u64 size, u64 align); GPUVAddr MapBufferEx(VAddr cpu_addr, u64 size); GPUVAddr MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size); - VAddr GpuToCpuAddress(GPUVAddr gpu_addr); + boost::optional GpuToCpuAddress(GPUVAddr gpu_addr); static constexpr u64 PAGE_BITS = 16; static constexpr u64 PAGE_SIZE = 1 << PAGE_BITS; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 8568d6762..71612790b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -150,7 +150,7 @@ std::pair RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, u64 size = end - start + 1; // Copy vertex array data - const VAddr data_addr{memory_manager->PhysicalToVirtualAddress(start)}; + const VAddr data_addr{*memory_manager->GpuToCpuAddress(start)}; res_cache.FlushRegion(data_addr, size, nullptr); Memory::ReadBlock(data_addr, array_ptr, size); @@ -233,8 +233,8 @@ void RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { // Fetch program code from memory GLShader::ProgramCode program_code; const u64 gpu_address{gpu.regs.code_address.CodeAddress() + shader_config.offset}; - const VAddr cpu_address{gpu.memory_manager.GpuToCpuAddress(gpu_address)}; - Memory::ReadBlock(cpu_address, program_code.data(), program_code.size() * sizeof(u64)); + const boost::optional cpu_address{gpu.memory_manager.GpuToCpuAddress(gpu_address)}; + Memory::ReadBlock(*cpu_address, program_code.data(), program_code.size() * sizeof(u64)); GLShader::ShaderSetup setup{std::move(program_code)}; GLShader::ShaderEntries shader_resources; @@ -394,9 +394,9 @@ void RasterizerOpenGL::DrawArrays() { GLintptr index_buffer_offset = 0; if (is_indexed) { const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager; - const VAddr index_data_addr{ + const boost::optional index_data_addr{ memory_manager->GpuToCpuAddress(regs.index_array.StartAddress())}; - Memory::ReadBlock(index_data_addr, offseted_buffer, index_buffer_size); + Memory::ReadBlock(*index_data_addr, offseted_buffer, index_buffer_size); index_buffer_offset = buffer_offset; offseted_buffer += index_buffer_size; @@ -659,9 +659,9 @@ u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, GLuint progr buffer_draw_state.enabled = true; buffer_draw_state.bindpoint = current_bindpoint + bindpoint; - VAddr addr = gpu.memory_manager->GpuToCpuAddress(buffer.address); + boost::optional addr = gpu.memory_manager->GpuToCpuAddress(buffer.address); std::vector data(used_buffer.GetSize() * sizeof(float)); - Memory::ReadBlock(addr, data.data(), data.size()); + Memory::ReadBlock(*addr, data.data(), data.size()); glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer_draw_state.ssbo); glBufferData(GL_SHADER_STORAGE_BUFFER, data.size(), data.data(), GL_DYNAMIC_DRAW); diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 46f0f25aa..ced648c12 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -1028,7 +1028,7 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu auto& gpu = Core::System::GetInstance().GPU(); SurfaceParams params; - params.addr = gpu.memory_manager->GpuToCpuAddress(config.tic.Address()); + params.addr = *gpu.memory_manager->GpuToCpuAddress(config.tic.Address()); params.width = config.tic.Width(); params.height = config.tic.Height(); params.is_tiled = config.tic.IsTiled(); @@ -1106,7 +1106,7 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces( color_params.block_height = Tegra::Texture::TICEntry::DefaultBlockHeight; SurfaceParams depth_params = color_params; - color_params.addr = memory_manager->GpuToCpuAddress(config.Address()); + color_params.addr = *memory_manager->GpuToCpuAddress(config.Address()); color_params.pixel_format = SurfaceParams::PixelFormatFromRenderTargetFormat(config.format); color_params.component_type = SurfaceParams::ComponentTypeFromRenderTarget(config.format); color_params.UpdateParams(); diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp index 5cadb807e..1fbca8ad0 100644 --- a/src/yuzu/debugger/graphics/graphics_surface.cpp +++ b/src/yuzu/debugger/graphics/graphics_surface.cpp @@ -378,10 +378,10 @@ void GraphicsSurfaceWidget::OnUpdate() { // TODO: Implement a good way to visualize alpha components! QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32); - VAddr address = gpu.memory_manager->GpuToCpuAddress(surface_address); + boost::optional address = gpu.memory_manager->GpuToCpuAddress(surface_address); auto unswizzled_data = - Tegra::Texture::UnswizzleTexture(address, surface_format, surface_width, surface_height); + Tegra::Texture::UnswizzleTexture(*address, surface_format, surface_width, surface_height); auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format, surface_width, surface_height); @@ -437,9 +437,9 @@ void GraphicsSurfaceWidget::SaveSurface() { pixmap->save(&file, "PNG"); } else if (selectedFilter == bin_filter) { auto& gpu = Core::System::GetInstance().GPU(); - VAddr address = gpu.memory_manager->GpuToCpuAddress(surface_address); + boost::optional address = gpu.memory_manager->GpuToCpuAddress(surface_address); - const u8* buffer = Memory::GetPointer(address); + const u8* buffer = Memory::GetPointer(*address); ASSERT_MSG(buffer != nullptr, "Memory not accessible"); QFile file(filename); -- cgit v1.2.3