/// <summary> /// Flushes the texture data, to be called from an external thread. /// The host backend must ensure that we have shared access to the resource from this thread. /// This is used when flushing from memory access handlers. /// </summary> public void ExternalFlush(ulong address, ulong size) { if (!IsModified || _memoryTracking == null) { return; } _context.Renderer.BackgroundContextAction(() => { IsModified = false; if (TextureCompatibility.IsFormatHostIncompatible(Info, _context.Capabilities)) { return; // Flushing this format is not supported, as it may have been converted to another host format. } ITexture texture = HostTexture; if (ScaleFactor != 1f) { // If needed, create a texture to flush back to host at 1x scale. texture = _flushHostTexture = GetScaledHostTexture(1f, _flushHostTexture); } _context.MemoryManager.WriteUntracked(Info.GpuAddress, GetTextureDataFromGpu(false, texture)); }); }
/// <summary> /// Flushes the texture data, to be called from an external thread. /// The host backend must ensure that we have shared access to the resource from this thread. /// This is used when flushing from memory access handlers. /// </summary> public void ExternalFlush(ulong address, ulong size) { if (!IsModified || _memoryTracking == null) { return; } _context.Renderer.BackgroundContextAction(() => { IsModified = false; if (TextureCompatibility.IsFormatHostIncompatible(Info, _context.Capabilities)) { return; // Flushing this format is not supported, as it may have been converted to another host format. } if (Info.Target == Target.Texture2DMultisample || Info.Target == Target.Texture2DMultisampleArray) { return; // Flushing multisample textures is not supported, the host does not allow getting their data. } ITexture texture = HostTexture; if (ScaleFactor != 1f) { // If needed, create a texture to flush back to host at 1x scale. texture = _flushHostTexture = GetScaledHostTexture(1f, _flushHostTexture); } _context.PhysicalMemory.WriteUntracked(Range, GetTextureDataFromGpu(false, texture)); }); }
/// <summary> /// Flushes the texture data. /// This causes the texture data to be written back to guest memory. /// If the texture was written by the GPU, this includes all modification made by the GPU /// up to this point. /// Be aware that this is an expensive operation, avoid calling it unless strictly needed. /// This may cause data corruption if the memory is already being used for something else on the CPU side. /// </summary> /// <param name="tracked">Whether or not the flush triggers write tracking. If it doesn't, the texture will not be blacklisted for scaling either.</param> public void Flush(bool tracked = true) { IsModified = false; if (TextureCompatibility.IsFormatHostIncompatible(Info, _context.Capabilities)) { return; // Flushing this format is not supported, as it may have been converted to another host format. } if (tracked) { _context.MemoryManager.Write(Info.GpuAddress, GetTextureDataFromGpu(tracked)); } else { _context.MemoryManager.WriteUntracked(Info.GpuAddress, GetTextureDataFromGpu(tracked)); } }