Vulkan/StagingTexture: Keep mapped throughout transfers
The underlying bug here was not invalidating the buffer after mapping (is this supposed to be necessary?). But by keeping it mapped, we invalidate it anyway. Fixes screen corruption in Final Fantasy IX on Mali GPUs.
This commit is contained in:
parent
e21fc9e253
commit
dd0ae0fc9d
|
@ -209,10 +209,8 @@ void StagingTexture::Flush()
|
|||
void StagingTexture::ReadTexels(u32 src_x, u32 src_y, u32 width, u32 height, void* out_ptr, u32 out_stride)
|
||||
{
|
||||
Assert(m_staging_buffer.GetType() != StagingBuffer::Type::Upload);
|
||||
if (!PrepareForAccess())
|
||||
return;
|
||||
|
||||
Assert((src_x + width) <= m_width && (src_y + height) <= m_height);
|
||||
PrepareForAccess();
|
||||
|
||||
// Offset pointer to point to start of region being copied out.
|
||||
const char* current_ptr = m_staging_buffer.GetMapPointer();
|
||||
|
@ -239,10 +237,9 @@ void StagingTexture::ReadTexels(u32 src_x, u32 src_y, u32 width, u32 height, voi
|
|||
void StagingTexture::ReadTexel(u32 x, u32 y, void* out_ptr)
|
||||
{
|
||||
Assert(m_staging_buffer.GetType() != StagingBuffer::Type::Upload);
|
||||
if (!PrepareForAccess())
|
||||
return;
|
||||
|
||||
Assert(x < m_width && y < m_height);
|
||||
PrepareForAccess();
|
||||
|
||||
const char* src_ptr = GetMappedPointer() + y * GetMappedStride() + x * m_texel_size;
|
||||
std::memcpy(out_ptr, src_ptr, m_texel_size);
|
||||
}
|
||||
|
@ -250,10 +247,8 @@ void StagingTexture::ReadTexel(u32 x, u32 y, void* out_ptr)
|
|||
void StagingTexture::WriteTexels(u32 dst_x, u32 dst_y, u32 width, u32 height, const void* in_ptr, u32 in_stride)
|
||||
{
|
||||
Assert(m_staging_buffer.GetType() != StagingBuffer::Type::Readback);
|
||||
if (!PrepareForAccess())
|
||||
return;
|
||||
|
||||
Assert((dst_x + width) <= m_width && (dst_y + height) <= m_height);
|
||||
PrepareForAccess();
|
||||
|
||||
// Offset pointer to point to start of region being copied to.
|
||||
char* current_ptr = GetMappedPointer();
|
||||
|
@ -279,23 +274,18 @@ void StagingTexture::WriteTexels(u32 dst_x, u32 dst_y, u32 width, u32 height, co
|
|||
|
||||
void StagingTexture::WriteTexel(u32 x, u32 y, const void* in_ptr)
|
||||
{
|
||||
if (!PrepareForAccess())
|
||||
return;
|
||||
|
||||
Assert(x < m_width && y < m_height);
|
||||
PrepareForAccess();
|
||||
|
||||
char* dest_ptr = GetMappedPointer() + y * m_map_stride + x * m_texel_size;
|
||||
std::memcpy(dest_ptr, in_ptr, m_texel_size);
|
||||
}
|
||||
|
||||
bool StagingTexture::PrepareForAccess()
|
||||
void StagingTexture::PrepareForAccess()
|
||||
{
|
||||
Assert(IsMapped());
|
||||
if (m_needs_flush)
|
||||
{
|
||||
if (IsMapped())
|
||||
Unmap();
|
||||
Flush();
|
||||
}
|
||||
return IsMapped() || Map();
|
||||
}
|
||||
|
||||
} // namespace Vulkan
|
|
@ -73,7 +73,7 @@ public:
|
|||
void WriteTexel(u32 x, u32 y, const void* in_ptr);
|
||||
|
||||
private:
|
||||
bool PrepareForAccess();
|
||||
void PrepareForAccess();
|
||||
|
||||
StagingBuffer m_staging_buffer;
|
||||
u64 m_flush_fence_counter = 0;
|
||||
|
|
Loading…
Reference in New Issue