[GPU] Ownership-transfer-based RT cache, 3x3 resolution scaling
The ROV path is also disabled by default because of lower performance
This commit is contained in:
@@ -249,7 +249,8 @@ void SharedMemory::FireWatches(uint32_t page_first, uint32_t page_last,
|
||||
}
|
||||
}
|
||||
|
||||
void SharedMemory::RangeWrittenByGpu(uint32_t start, uint32_t length) {
|
||||
void SharedMemory::RangeWrittenByGpu(uint32_t start, uint32_t length,
|
||||
bool is_resolve) {
|
||||
if (length == 0 || start >= kBufferSize) {
|
||||
return;
|
||||
}
|
||||
@@ -264,7 +265,7 @@ void SharedMemory::RangeWrittenByGpu(uint32_t start, uint32_t length) {
|
||||
|
||||
// Mark the range as valid (so pages are not reuploaded until modified by the
|
||||
// CPU) and watch it so the CPU can reuse it and this will be caught.
|
||||
MakeRangeValid(start, length, true);
|
||||
MakeRangeValid(start, length, true, is_resolve);
|
||||
}
|
||||
|
||||
bool SharedMemory::AllocateSparseHostGpuMemoryRange(
|
||||
@@ -276,7 +277,9 @@ bool SharedMemory::AllocateSparseHostGpuMemoryRange(
|
||||
}
|
||||
|
||||
void SharedMemory::MakeRangeValid(uint32_t start, uint32_t length,
|
||||
bool written_by_gpu) {
|
||||
bool written_by_gpu,
|
||||
bool written_by_gpu_resolve) {
|
||||
assert_false(written_by_gpu_resolve && !written_by_gpu);
|
||||
if (length == 0 || start >= kBufferSize) {
|
||||
return;
|
||||
}
|
||||
@@ -305,6 +308,11 @@ void SharedMemory::MakeRangeValid(uint32_t start, uint32_t length,
|
||||
} else {
|
||||
block.valid_and_gpu_written &= ~valid_bits;
|
||||
}
|
||||
if (written_by_gpu_resolve) {
|
||||
block.valid_and_gpu_resolved |= valid_bits;
|
||||
} else {
|
||||
block.valid_and_gpu_resolved &= ~valid_bits;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,9 +347,13 @@ void SharedMemory::UnlinkWatchRange(WatchRange* range) {
|
||||
watch_range_first_free_ = range;
|
||||
}
|
||||
|
||||
bool SharedMemory::RequestRange(uint32_t start, uint32_t length) {
|
||||
bool SharedMemory::RequestRange(uint32_t start, uint32_t length,
|
||||
bool* any_data_resolved_out) {
|
||||
if (!length) {
|
||||
// Some texture or buffer is empty, for example - safe to draw in this case.
|
||||
if (any_data_resolved_out) {
|
||||
*any_data_resolved_out = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (start > kBufferSize || (kBufferSize - start) < length) {
|
||||
@@ -358,19 +370,29 @@ bool SharedMemory::RequestRange(uint32_t start, uint32_t length) {
|
||||
uint32_t page_last = (start + length - 1) >> page_size_log2_;
|
||||
|
||||
upload_ranges_.clear();
|
||||
bool any_data_resolved = false;
|
||||
uint32_t block_first = page_first >> 6;
|
||||
uint32_t block_last = page_last >> 6;
|
||||
uint32_t range_start = UINT32_MAX;
|
||||
{
|
||||
auto global_lock = global_critical_region_.Acquire();
|
||||
for (uint32_t i = block_first; i <= block_last; ++i) {
|
||||
uint64_t block_valid = system_page_flags_[i].valid;
|
||||
const SystemPageFlagsBlock& block = system_page_flags_[i];
|
||||
uint64_t block_valid = block.valid;
|
||||
uint64_t block_resolved = block.valid_and_gpu_resolved;
|
||||
// Consider pages in the block outside the requested range valid.
|
||||
if (i == block_first) {
|
||||
block_valid |= (uint64_t(1) << (page_first & 63)) - 1;
|
||||
uint64_t block_before = (uint64_t(1) << (page_first & 63)) - 1;
|
||||
block_valid |= block_before;
|
||||
block_resolved &= ~block_before;
|
||||
}
|
||||
if (i == block_last && (page_last & 63) != 63) {
|
||||
block_valid |= ~((uint64_t(1) << ((page_last & 63) + 1)) - 1);
|
||||
uint64_t block_inside = (uint64_t(1) << ((page_last & 63) + 1)) - 1;
|
||||
block_valid |= ~block_inside;
|
||||
block_resolved &= block_inside;
|
||||
}
|
||||
if (block_resolved) {
|
||||
any_data_resolved = true;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
@@ -406,6 +428,9 @@ bool SharedMemory::RequestRange(uint32_t start, uint32_t length) {
|
||||
upload_ranges_.push_back(
|
||||
std::make_pair(range_start, page_last + 1 - range_start));
|
||||
}
|
||||
if (any_data_resolved_out) {
|
||||
*any_data_resolved_out = any_data_resolved;
|
||||
}
|
||||
if (upload_ranges_.empty()) {
|
||||
return true;
|
||||
}
|
||||
@@ -470,6 +495,7 @@ std::pair<uint32_t, uint32_t> SharedMemory::MemoryInvalidationCallback(
|
||||
SystemPageFlagsBlock& block = system_page_flags_[i];
|
||||
block.valid &= ~invalidate_bits;
|
||||
block.valid_and_gpu_written &= ~invalidate_bits;
|
||||
block.valid_and_gpu_resolved &= ~invalidate_bits;
|
||||
}
|
||||
|
||||
FireWatches(page_first, page_last, false);
|
||||
|
||||
Reference in New Issue
Block a user