[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:
Triang3l
2021-04-26 22:12:09 +03:00
parent 30ea6e3ea3
commit 913e1e949c
362 changed files with 185259 additions and 38291 deletions

View File

@@ -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);