mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 06:39:46 -06:00
Memmap: Replace GetPointer with GetSpanForAddress
To ensure memory safety, callers of GetPointer have to perform a bounds check. But how is this bounds check supposed to be performed? GetPointerForRange contained one implementation of a bounds check, but it was cumbersome, and it also isn't obvious why it's correct. To make doing the right thing easier, this commit changes GetPointer to return a span that tells the caller how many bytes it's allowed to access.
This commit is contained in:
@ -3,6 +3,8 @@
|
||||
|
||||
#include "VideoCommon/TextureInfo.h"
|
||||
|
||||
#include <span>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <xxhash.h>
|
||||
|
||||
@ -47,8 +49,10 @@ TextureInfo TextureInfo::FromStage(u32 stage)
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
auto& memory = system.GetMemory();
|
||||
return TextureInfo(stage, memory.GetPointer(address), tlut_ptr, address, texture_format,
|
||||
tlut_format, width, height, false, nullptr, nullptr, mip_count);
|
||||
// TODO: For memory safety, we need to check the size of this span
|
||||
std::span<const u8> span = memory.GetSpanForAddress(address);
|
||||
return TextureInfo(stage, span.data(), tlut_ptr, address, texture_format, tlut_format, width,
|
||||
height, false, nullptr, nullptr, mip_count);
|
||||
}
|
||||
|
||||
TextureInfo::TextureInfo(u32 stage, const u8* ptr, const u8* tlut_ptr, u32 address,
|
||||
|
@ -91,26 +91,35 @@ void UpdateVertexArrayPointers()
|
||||
// Note: Only array bases 0 through 11 are used by the Vertex loaders.
|
||||
// 12 through 15 are used for loading data into xfmem.
|
||||
// We also only update the array base if the vertex description states we are going to use it.
|
||||
// TODO: For memory safety, we need to check the sizes returned by GetSpanForAddress
|
||||
if (IsIndexed(g_main_cp_state.vtx_desc.low.Position))
|
||||
{
|
||||
cached_arraybases[CPArray::Position] =
|
||||
memory.GetPointer(g_main_cp_state.array_bases[CPArray::Position]);
|
||||
memory.GetSpanForAddress(g_main_cp_state.array_bases[CPArray::Position]).data();
|
||||
}
|
||||
|
||||
if (IsIndexed(g_main_cp_state.vtx_desc.low.Normal))
|
||||
{
|
||||
cached_arraybases[CPArray::Normal] =
|
||||
memory.GetPointer(g_main_cp_state.array_bases[CPArray::Normal]);
|
||||
memory.GetSpanForAddress(g_main_cp_state.array_bases[CPArray::Normal]).data();
|
||||
}
|
||||
|
||||
for (u8 i = 0; i < g_main_cp_state.vtx_desc.low.Color.Size(); i++)
|
||||
{
|
||||
if (IsIndexed(g_main_cp_state.vtx_desc.low.Color[i]))
|
||||
{
|
||||
cached_arraybases[CPArray::Color0 + i] =
|
||||
memory.GetPointer(g_main_cp_state.array_bases[CPArray::Color0 + i]);
|
||||
memory.GetSpanForAddress(g_main_cp_state.array_bases[CPArray::Color0 + i]).data();
|
||||
}
|
||||
}
|
||||
|
||||
for (u8 i = 0; i < g_main_cp_state.vtx_desc.high.TexCoord.Size(); i++)
|
||||
{
|
||||
if (IsIndexed(g_main_cp_state.vtx_desc.high.TexCoord[i]))
|
||||
{
|
||||
cached_arraybases[CPArray::TexCoord0 + i] =
|
||||
memory.GetPointer(g_main_cp_state.array_bases[CPArray::TexCoord0 + i]);
|
||||
memory.GetSpanForAddress(g_main_cp_state.array_bases[CPArray::TexCoord0 + i]).data();
|
||||
}
|
||||
}
|
||||
|
||||
g_bases_dirty = false;
|
||||
|
Reference in New Issue
Block a user