From 54773bc5d2c847bc4e070a8a647b97a9fc76bcb0 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sun, 7 Apr 2024 11:13:25 +0200 Subject: [PATCH] VideoCommon: Remove calls to GetPointer This fourth part of my series of patches to get rid of unsafe uses of GetPointer takes care of the "easy" cases in VideoCommon. Three uses of GetPointer now remain in Dolphin: VertexLoaderManager, TextureInfo, and the software renderer's TextureSampler. --- Source/Core/VideoCommon/BPStructs.cpp | 8 +++-- Source/Core/VideoCommon/OpcodeDecoding.cpp | 6 ++-- Source/Core/VideoCommon/TextureCacheBase.cpp | 32 +++++++++++--------- Source/Core/VideoCommon/XFStructs.cpp | 18 ++++++----- 4 files changed, 36 insertions(+), 28 deletions(-) diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp index 0b8540bd44de..6e4bb981a8cf 100644 --- a/Source/Core/VideoCommon/BPStructs.cpp +++ b/Source/Core/VideoCommon/BPStructs.cpp @@ -602,7 +602,6 @@ static void BPWritten(PixelShaderManager& pixel_shader_manager, XFStateManager& { auto& system = Core::System::GetInstance(); auto& memory = system.GetMemory(); - u8* src_ptr = memory.GetPointer(src_addr); // AR and GB tiles are stored in separate TMEM banks => can't use a single memcpy for // everything @@ -612,10 +611,13 @@ static void BPWritten(PixelShaderManager& pixel_shader_manager, XFStateManager& { if (tmem_addr_even + TMEM_LINE_SIZE > TMEM_SIZE || tmem_addr_odd + TMEM_LINE_SIZE > TMEM_SIZE) + { break; + } - memcpy(texMem + tmem_addr_even, src_ptr + bytes_read, TMEM_LINE_SIZE); - memcpy(texMem + tmem_addr_odd, src_ptr + bytes_read + TMEM_LINE_SIZE, TMEM_LINE_SIZE); + memory.CopyFromEmu(texMem + tmem_addr_even, src_addr + bytes_read, TMEM_LINE_SIZE); + memory.CopyFromEmu(texMem + tmem_addr_odd, src_addr + bytes_read + TMEM_LINE_SIZE, + TMEM_LINE_SIZE); tmem_addr_even += TMEM_LINE_SIZE; tmem_addr_odd += TMEM_LINE_SIZE; bytes_read += TMEM_LINE_SIZE * 2; diff --git a/Source/Core/VideoCommon/OpcodeDecoding.cpp b/Source/Core/VideoCommon/OpcodeDecoding.cpp index 1456fbf2d09f..768356aea8a9 100644 --- a/Source/Core/VideoCommon/OpcodeDecoding.cpp +++ b/Source/Core/VideoCommon/OpcodeDecoding.cpp @@ -158,7 +158,7 @@ class RunCallback final : public Callback if constexpr (is_preprocess) { auto& memory = system.GetMemory(); - const u8* const start_address = memory.GetPointer(address); + const u8* const start_address = memory.GetPointerForRange(address, size); system.GetFifo().PushFifoAuxBuffer(start_address, size); @@ -179,10 +179,10 @@ class RunCallback final : public Callback else { auto& memory = system.GetMemory(); - start_address = memory.GetPointer(address); + start_address = memory.GetPointerForRange(address, size); } - // Avoid the crash if memory.GetPointer failed .. + // Avoid the crash if memory.GetPointerForRange failed .. if (start_address != nullptr) { // temporarily swap dl and non-dl (small "hack" for the stats) diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index fbe4f107bf1d..d6fec6adc4b1 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -1872,9 +1872,12 @@ static void GetDisplayRectForXFBEntry(TCacheEntry* entry, u32 width, u32 height, RcTcacheEntry TextureCacheBase::GetXFBTexture(u32 address, u32 width, u32 height, u32 stride, MathUtil::Rectangle* display_rect) { + // Compute total texture size. XFB textures aren't tiled, so this is simple. + const u32 total_size = height * stride; + auto& system = Core::System::GetInstance(); auto& memory = system.GetMemory(); - const u8* src_data = memory.GetPointer(address); + const u8* src_data = memory.GetPointerForRange(address, total_size); if (!src_data) { ERROR_LOG_FMT(VIDEO, "Trying to load XFB texture from invalid address {:#010x}", address); @@ -1900,8 +1903,6 @@ RcTcacheEntry TextureCacheBase::GetXFBTexture(u32 address, u32 width, u32 height AbstractTextureFlag_RenderTarget, AbstractTextureType::Texture_2DArray)); - // Compute total texture size. XFB textures aren't tiled, so this is simple. - const u32 total_size = height * stride; entry->SetGeneralParameters(address, total_size, TextureAndTLUTFormat(TextureFormat::XFB, TLUTFormat::IA8), true); entry->SetDimensions(width, height, 1); @@ -2250,15 +2251,6 @@ void TextureCacheBase::CopyRenderTargetToTexture( !(is_xfb_copy ? g_ActiveConfig.bSkipXFBCopyToRam : g_ActiveConfig.bSkipEFBCopyToRam) || !copy_to_vram; - auto& system = Core::System::GetInstance(); - auto& memory = system.GetMemory(); - u8* dst = memory.GetPointer(dstAddr); - if (dst == nullptr) - { - ERROR_LOG_FMT(VIDEO, "Trying to copy from EFB to invalid address {:#010x}", dstAddr); - return; - } - // tex_w and tex_h are the native size of the texture in the GC memory. // The size scaled_* represents the emulated texture. Those differ // because of upscaling and because of yscaling of XFB copies. @@ -2302,6 +2294,15 @@ void TextureCacheBase::CopyRenderTargetToTexture( const u32 bytes_per_row = num_blocks_x * bytes_per_block; const u32 covered_range = num_blocks_y * dstStride; + auto& system = Core::System::GetInstance(); + auto& memory = system.GetMemory(); + u8* dst = memory.GetPointerForRange(dstAddr, covered_range); + if (dst == nullptr) + { + ERROR_LOG_FMT(VIDEO, "Trying to copy from EFB to invalid address {:#010x}", dstAddr); + return; + } + if (g_ActiveConfig.bGraphicMods) { FBInfo info; @@ -2576,10 +2577,12 @@ void TextureCacheBase::WriteEFBCopyToRAM(u8* dst_ptr, u32 width, u32 height, u32 void TextureCacheBase::FlushEFBCopy(TCacheEntry* entry) { + const u32 covered_range = entry->pending_efb_copy_height * entry->memory_stride; + // Copy from texture -> guest memory. auto& system = Core::System::GetInstance(); auto& memory = system.GetMemory(); - u8* const dst = memory.GetPointer(entry->addr); + u8* const dst = memory.GetPointerForRange(entry->addr, covered_range); WriteEFBCopyToRAM(dst, entry->pending_efb_copy_width, entry->pending_efb_copy_height, entry->memory_stride, std::move(entry->pending_efb_copy)); @@ -2597,7 +2600,6 @@ void TextureCacheBase::FlushEFBCopy(TCacheEntry* entry) // See the comment above regarding Rogue Squadron 2. if (entry->is_xfb_copy) { - const u32 covered_range = entry->pending_efb_copy_height * entry->memory_stride; auto range = FindOverlappingTextures(entry->addr, covered_range); for (auto iter = range.first; iter != range.second; ++iter) { @@ -3164,7 +3166,7 @@ u64 TCacheEntry::CalculateHash() const // FIXME: textures from tmem won't get the correct hash. auto& system = Core::System::GetInstance(); auto& memory = system.GetMemory(); - u8* ptr = memory.GetPointer(addr); + u8* ptr = memory.GetPointerForRange(addr, size_in_bytes); if (memory_stride == bytes_per_row) { return Common::GetHash64(ptr, size_in_bytes, hash_sample_size); diff --git a/Source/Core/VideoCommon/XFStructs.cpp b/Source/Core/VideoCommon/XFStructs.cpp index 906c37bb5a49..33f47a01a5f7 100644 --- a/Source/Core/VideoCommon/XFStructs.cpp +++ b/Source/Core/VideoCommon/XFStructs.cpp @@ -259,19 +259,21 @@ void LoadIndexedXF(CPArray array, u32 index, u16 address, u8 size) { // load stuff from array to address in xf mem - u32* currData = (u32*)(&xfmem) + address; + const u32 buf_size = size * sizeof(u32); + u32* currData = reinterpret_cast(&xfmem) + address; u32* newData; auto& system = Core::System::GetInstance(); auto& fifo = system.GetFifo(); if (fifo.UseDeterministicGPUThread()) { - newData = (u32*)fifo.PopFifoAuxBuffer(size * sizeof(u32)); + newData = reinterpret_cast(fifo.PopFifoAuxBuffer(buf_size)); } else { auto& memory = system.GetMemory(); - newData = (u32*)memory.GetPointer(g_main_cp_state.array_bases[array] + - g_main_cp_state.array_strides[array] * index); + newData = reinterpret_cast(memory.GetPointerForRange( + g_main_cp_state.array_bases[array] + g_main_cp_state.array_strides[array] * index, + buf_size)); } auto& xf_state_manager = system.GetXFStateManager(); @@ -294,12 +296,14 @@ void LoadIndexedXF(CPArray array, u32 index, u16 address, u8 size) void PreprocessIndexedXF(CPArray array, u32 index, u16 address, u8 size) { + const size_t buf_size = size * sizeof(u32); + auto& system = Core::System::GetInstance(); auto& memory = system.GetMemory(); - const u8* new_data = memory.GetPointer(g_preprocess_cp_state.array_bases[array] + - g_preprocess_cp_state.array_strides[array] * index); + const u8* new_data = memory.GetPointerForRange( + g_preprocess_cp_state.array_bases[array] + g_preprocess_cp_state.array_strides[array] * index, + buf_size); - const size_t buf_size = size * sizeof(u32); system.GetFifo().PushFifoAuxBuffer(new_data, buf_size); }