mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 21:32:50 +00:00
rsx: Fix segmented memory access for rsx::super_ptr
This commit is contained in:
parent
d283200e13
commit
fbf6581249
@ -559,6 +559,7 @@ namespace gl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flush_io();
|
||||||
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
||||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, GL_NONE);
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, GL_NONE);
|
||||||
|
|
||||||
|
@ -323,6 +323,7 @@ namespace vk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flush_io();
|
||||||
dma_buffer->unmap();
|
dma_buffer->unmap();
|
||||||
reset_write_statistics();
|
reset_write_statistics();
|
||||||
|
|
||||||
|
@ -43,6 +43,8 @@ namespace rsx
|
|||||||
|
|
||||||
*first = cpu_address_base + confirmed_range.first;
|
*first = cpu_address_base + confirmed_range.first;
|
||||||
*last = cpu_address_base + valid_limit - 4;
|
*last = cpu_address_base + valid_limit - 4;
|
||||||
|
|
||||||
|
locked_memory_ptr.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,13 +321,13 @@ namespace rsx
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T = void>
|
template <typename T = void>
|
||||||
T* get_raw_ptr(u32 offset = 0) const
|
T* get_raw_ptr(u32 offset = 0)
|
||||||
{
|
{
|
||||||
verify(HERE), locked_memory_ptr;
|
verify(HERE), locked_memory_ptr;
|
||||||
return locked_memory_ptr.get<T>(offset);
|
return locked_memory_ptr.get<T>(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_memory_head() const
|
bool test_memory_head()
|
||||||
{
|
{
|
||||||
if (!locked_memory_ptr)
|
if (!locked_memory_ptr)
|
||||||
{
|
{
|
||||||
@ -336,7 +338,7 @@ namespace rsx
|
|||||||
return (*first == (cpu_address_base + confirmed_range.first));
|
return (*first == (cpu_address_base + confirmed_range.first));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_memory_tail() const
|
bool test_memory_tail()
|
||||||
{
|
{
|
||||||
if (!locked_memory_ptr)
|
if (!locked_memory_ptr)
|
||||||
{
|
{
|
||||||
@ -348,6 +350,11 @@ namespace rsx
|
|||||||
return (*last == (cpu_address_base + valid_limit - 4));
|
return (*last == (cpu_address_base + valid_limit - 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void flush_io() const
|
||||||
|
{
|
||||||
|
locked_memory_ptr.flush();
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<u32, u32> get_confirmed_range() const
|
std::pair<u32, u32> get_confirmed_range() const
|
||||||
{
|
{
|
||||||
if (confirmed_range.second == 0)
|
if (confirmed_range.second == 0)
|
||||||
|
@ -109,14 +109,40 @@ namespace rsx
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = vm::get_super_ptr<u8>(addr, len - 1);
|
if (auto result = vm::get_super_ptr<u8>(addr, len - 1))
|
||||||
if (!result)
|
|
||||||
{
|
{
|
||||||
//Probably allocated as split blocks??
|
return { result };
|
||||||
LOG_ERROR(RSX, "Could not get super_ptr for memory block 0x%x+0x%x", addr, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return { result };
|
//Probably allocated as split blocks. Try to grab separate chunks
|
||||||
|
std::vector<weak_ptr::memory_block_t> blocks;
|
||||||
|
const u32 limit = addr + len;
|
||||||
|
u32 next = addr;
|
||||||
|
u32 remaining = len;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
auto region = vm::get(vm::any, next)->get(next, 1);
|
||||||
|
if (!region.second)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u32 block_offset = next - region.first;
|
||||||
|
const u32 block_length = std::min(remaining, region.second->size() - block_offset);
|
||||||
|
std::shared_ptr<u8> _ptr = { region.second, region.second->get(block_offset, block_length) };
|
||||||
|
blocks.push_back({_ptr, block_length});
|
||||||
|
|
||||||
|
remaining -= block_length;
|
||||||
|
next = region.first + region.second->size();
|
||||||
|
if (next >= limit)
|
||||||
|
{
|
||||||
|
return { blocks };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_ERROR(RSX, "Could not get super_ptr for memory block 0x%x+0x%x", addr, len);
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fast image scaling routines
|
/* Fast image scaling routines
|
||||||
|
@ -35,21 +35,60 @@ namespace rsx
|
|||||||
//Weak pointer without lock semantics
|
//Weak pointer without lock semantics
|
||||||
//Backed by a real shared_ptr for non-rsx memory
|
//Backed by a real shared_ptr for non-rsx memory
|
||||||
//Backed by a global shared pool for rsx memory
|
//Backed by a global shared pool for rsx memory
|
||||||
struct weak_ptr
|
class weak_ptr
|
||||||
{
|
{
|
||||||
void* _ptr;
|
public:
|
||||||
std::shared_ptr<u8> _extern;
|
using memory_block_t = std::pair<std::shared_ptr<u8>, u32>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void* _ptr = nullptr;
|
||||||
|
std::vector<memory_block_t> _blocks;
|
||||||
|
std::vector<u8> io_cache;
|
||||||
|
bool contiguous = true;
|
||||||
|
bool synchronized = true;
|
||||||
|
|
||||||
|
public:
|
||||||
weak_ptr(void* raw, bool is_rsx_mem = true)
|
weak_ptr(void* raw, bool is_rsx_mem = true)
|
||||||
{
|
{
|
||||||
_ptr = raw;
|
_ptr = raw;
|
||||||
if (!is_rsx_mem) _extern.reset((u8*)raw);
|
|
||||||
|
if (!is_rsx_mem)
|
||||||
|
{
|
||||||
|
_blocks.push_back({});
|
||||||
|
_blocks.back().first.reset((u8*)raw);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
weak_ptr(std::shared_ptr<u8>& block)
|
weak_ptr(std::shared_ptr<u8>& block)
|
||||||
{
|
{
|
||||||
_extern = block;
|
_blocks.push_back({ block, 0 });
|
||||||
_ptr = _extern.get();
|
_ptr = block.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
weak_ptr(std::vector<memory_block_t>& blocks)
|
||||||
|
{
|
||||||
|
verify(HERE), blocks.size() > 0;
|
||||||
|
|
||||||
|
_blocks = std::move(blocks);
|
||||||
|
_ptr = nullptr;
|
||||||
|
|
||||||
|
if (blocks.size() == 1)
|
||||||
|
{
|
||||||
|
_ptr = _blocks[0].first.get();
|
||||||
|
contiguous = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u32 block_length = 0;
|
||||||
|
for (const auto &block : _blocks)
|
||||||
|
{
|
||||||
|
block_length += block.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
io_cache.resize(block_length);
|
||||||
|
contiguous = false;
|
||||||
|
synchronized = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
weak_ptr()
|
weak_ptr()
|
||||||
@ -58,14 +97,52 @@ namespace rsx
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T = void>
|
template <typename T = void>
|
||||||
T* get(u32 offset = 0) const
|
T* get(u32 offset = 0)
|
||||||
{
|
{
|
||||||
return (T*)((u8*)_ptr + offset);
|
if (contiguous)
|
||||||
|
{
|
||||||
|
return (T*)((u8*)_ptr + offset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!synchronized)
|
||||||
|
sync();
|
||||||
|
|
||||||
|
return (T*)(io_cache.data() + offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sync()
|
||||||
|
{
|
||||||
|
if (synchronized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
u8* dst = (u8*)io_cache.data();
|
||||||
|
for (const auto &block : _blocks)
|
||||||
|
{
|
||||||
|
memcpy(dst, block.first.get(), block.second);
|
||||||
|
dst += block.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush() const
|
||||||
|
{
|
||||||
|
if (contiguous)
|
||||||
|
return;
|
||||||
|
|
||||||
|
u8* src = (u8*)io_cache.data();
|
||||||
|
for (const auto &block : _blocks)
|
||||||
|
{
|
||||||
|
memcpy(block.first.get(), src, block.second);
|
||||||
|
src += block.second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
operator bool() const
|
operator bool() const
|
||||||
{
|
{
|
||||||
return (_ptr != nullptr);
|
return (_ptr != nullptr || _blocks.size() > 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user