surface_base: Implement texture buffer flushes

Implement downloads to guest memory from texture buffers on the generic
cache and OpenGL.
This commit is contained in:
ReinUsesLisp 2020-02-16 00:10:32 -03:00
parent f552d553ba
commit fd62bdf377
2 changed files with 11 additions and 0 deletions

View File

@ -260,6 +260,13 @@ CachedSurface::~CachedSurface() = default;
void CachedSurface::DownloadTexture(std::vector<u8>& staging_buffer) { void CachedSurface::DownloadTexture(std::vector<u8>& staging_buffer) {
MICROPROFILE_SCOPE(OpenGL_Texture_Download); MICROPROFILE_SCOPE(OpenGL_Texture_Download);
if (params.IsBuffer()) {
glGetNamedBufferSubData(texture_buffer.handle, 0,
static_cast<GLsizeiptr>(params.GetHostSizeInBytes()),
staging_buffer.data());
return;
}
SCOPE_EXIT({ glPixelStorei(GL_PACK_ROW_LENGTH, 0); }); SCOPE_EXIT({ glPixelStorei(GL_PACK_ROW_LENGTH, 0); });
for (u32 level = 0; level < params.emulated_levels; ++level) { for (u32 level = 0; level < params.emulated_levels; ++level) {

View File

@ -277,6 +277,10 @@ void SurfaceBaseImpl::FlushBuffer(Tegra::MemoryManager& memory_manager,
SwizzleFunc(MortonSwizzleMode::LinearToMorton, host_ptr, params, SwizzleFunc(MortonSwizzleMode::LinearToMorton, host_ptr, params,
staging_buffer.data() + host_offset, level); staging_buffer.data() + host_offset, level);
} }
} else if (params.IsBuffer()) {
// Buffers don't have pitch or any fancy layout property. We can just memcpy them to guest
// memory.
std::memcpy(host_ptr, staging_buffer.data(), guest_memory_size);
} else { } else {
ASSERT(params.target == SurfaceTarget::Texture2D); ASSERT(params.target == SurfaceTarget::Texture2D);
ASSERT(params.num_levels == 1); ASSERT(params.num_levels == 1);