[GPU] Double-buffer readback_resolve.
Introduce "fast" readback resolve that reads from previous frame's resolve buffers, quick swap between buffers each frame to avoid copies so minimal performance impact and mostly correct bahavior. Checks if previous frame had a buffer for the current resolve and falls through to the slow path, which also allows to support "screenshot" features in the games that do that without stalling on normal resolve operations. Re-enabled readback_memexport as separate feature, was previously bundled with readback_resolve (probably not intentionally) and ensures destination address is writeable to avoid memory access related crashes and unnecessary work. readback_resolve cvar changes from bool to string ternary with "none", "fast" and "full" options, defaulting to the new "fast" mode.
This commit is contained in:
committed by
Radosław Gliński
parent
93adb2bb95
commit
e2c33686cc
@@ -33,14 +33,18 @@ class ByteStream;
|
||||
|
||||
namespace gpu {
|
||||
|
||||
enum class GPUSetting {
|
||||
ClearMemoryPageState,
|
||||
ReadbackResolve,
|
||||
ReadbackMemexport
|
||||
enum class GPUSetting { ClearMemoryPageState, ReadbackMemexport };
|
||||
|
||||
enum class ReadbackResolveMode {
|
||||
kDisabled, // No readback (none)
|
||||
kFast, // Delayed sync, 1 frame behind (fast)
|
||||
kFull // Immediate sync with GPU stall (full)
|
||||
};
|
||||
|
||||
void SaveGPUSetting(GPUSetting setting, uint64_t value);
|
||||
bool GetGPUSetting(GPUSetting setting);
|
||||
ReadbackResolveMode GetReadbackResolveMode();
|
||||
void SetReadbackResolveMode(const std::string& mode);
|
||||
|
||||
class GraphicsSystem;
|
||||
class Shader;
|
||||
@@ -162,6 +166,27 @@ class CommandProcessor {
|
||||
|
||||
static constexpr uint32_t kReadbackBufferSizeIncrement = 16 * 1024 * 1024;
|
||||
|
||||
// Eviction policy constants for readback buffer cache
|
||||
static constexpr size_t kMaxReadbackBuffers = 64;
|
||||
static constexpr uint64_t kReadbackBufferEvictionAgeFrames = 60;
|
||||
|
||||
// Progressive alignment for readback buffers to avoid wasting memory
|
||||
static inline uint32_t AlignReadbackBufferSize(uint32_t size) {
|
||||
if (size < 1 * 1024 * 1024) {
|
||||
return xe::align(size, 256u * 1024u); // 256KB for < 1MB
|
||||
} else if (size < 4 * 1024 * 1024) {
|
||||
return xe::align(size, 1u * 1024u * 1024u); // 1MB for < 4MB
|
||||
} else {
|
||||
return xe::align(size, kReadbackBufferSizeIncrement); // 16MB for >= 4MB
|
||||
}
|
||||
}
|
||||
|
||||
// Generate a cache key for a specific resolve operation
|
||||
static inline uint64_t MakeReadbackResolveKey(uint32_t address,
|
||||
uint32_t length) {
|
||||
return (uint64_t(address) << 32) | uint64_t(length);
|
||||
}
|
||||
|
||||
void WorkerThreadMain();
|
||||
virtual bool SetupContext() = 0;
|
||||
virtual void ShutdownContext() = 0;
|
||||
|
||||
Reference in New Issue
Block a user