[D3D12] SHM upload range cleanup and mask index buffer address
This commit is contained in:
parent
ecfa70284e
commit
005e590c92
|
@ -1037,7 +1037,8 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
||||||
? sizeof(uint32_t)
|
? sizeof(uint32_t)
|
||||||
: sizeof(uint16_t);
|
: sizeof(uint16_t);
|
||||||
assert_false(index_buffer_info->guest_base & (index_size - 1));
|
assert_false(index_buffer_info->guest_base & (index_size - 1));
|
||||||
uint32_t index_base = index_buffer_info->guest_base & ~(index_size - 1);
|
uint32_t index_base =
|
||||||
|
index_buffer_info->guest_base & 0x1FFFFFFF & ~(index_size - 1);
|
||||||
D3D12_INDEX_BUFFER_VIEW index_buffer_view;
|
D3D12_INDEX_BUFFER_VIEW index_buffer_view;
|
||||||
index_buffer_view.Format = index_buffer_info->format == IndexFormat::kInt32
|
index_buffer_view.Format = index_buffer_info->format == IndexFormat::kInt32
|
||||||
? DXGI_FORMAT_R32_UINT
|
? DXGI_FORMAT_R32_UINT
|
||||||
|
|
|
@ -274,10 +274,7 @@ bool SharedMemory::RequestRange(uint32_t start, uint32_t length) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upload and protect used ranges.
|
// Upload and protect used ranges.
|
||||||
GetRangesToUpload(start >> page_size_log2_,
|
GetRangesToUpload(start >> page_size_log2_, last >> page_size_log2_);
|
||||||
((start & ((1 << page_size_log2_) - 1)) + length +
|
|
||||||
((1 << page_size_log2_) - 1)) >>
|
|
||||||
page_size_log2_);
|
|
||||||
if (upload_ranges_.size() == 0) {
|
if (upload_ranges_.size() == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -402,14 +399,12 @@ void SharedMemory::UnlinkWatchRange(WatchRange* range) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SharedMemory::GetRangesToUpload(uint32_t request_page_first,
|
void SharedMemory::GetRangesToUpload(uint32_t request_page_first,
|
||||||
uint32_t request_page_count) {
|
uint32_t request_page_last) {
|
||||||
upload_ranges_.clear();
|
upload_ranges_.clear();
|
||||||
if (request_page_first >= page_count_ || request_page_count == 0) {
|
request_page_last = std::min(request_page_last, page_count_ - 1u);
|
||||||
|
if (request_page_first > request_page_last) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
request_page_count =
|
|
||||||
std::min(request_page_count, page_count_ - request_page_first);
|
|
||||||
uint32_t request_page_last = request_page_first + request_page_count - 1;
|
|
||||||
uint32_t request_block_first = request_page_first >> 6;
|
uint32_t request_block_first = request_page_first >> 6;
|
||||||
uint32_t request_block_last = request_page_last >> 6;
|
uint32_t request_block_last = request_page_last >> 6;
|
||||||
|
|
||||||
|
@ -418,43 +413,39 @@ void SharedMemory::GetRangesToUpload(uint32_t request_page_first,
|
||||||
uint32_t range_start = UINT32_MAX;
|
uint32_t range_start = UINT32_MAX;
|
||||||
for (uint32_t i = request_block_first; i <= request_block_last; ++i) {
|
for (uint32_t i = request_block_first; i <= request_block_last; ++i) {
|
||||||
uint64_t block_valid = valid_pages_[i];
|
uint64_t block_valid = valid_pages_[i];
|
||||||
uint64_t block_invalid = ~block_valid;
|
// Consider pages in the block outside the requested range valid.
|
||||||
|
|
||||||
// Ignore pages outside the requested range in bits scans completely.
|
|
||||||
uint64_t bits_to_keep;
|
|
||||||
if (i == request_block_first) {
|
if (i == request_block_first) {
|
||||||
bits_to_keep = ~((1ull << (request_page_first & 63)) - 1);
|
block_valid |= (1ull << (request_page_first & 63)) - 1;
|
||||||
block_valid &= bits_to_keep;
|
|
||||||
block_invalid &= bits_to_keep;
|
|
||||||
}
|
}
|
||||||
if (i == request_block_last && (request_page_last & 63) != 63) {
|
if (i == request_block_last && (request_page_last & 63) != 63) {
|
||||||
bits_to_keep = (1ull << ((request_page_last & 63) + 1)) - 1;
|
block_valid |= ~((1ull << ((request_page_last & 63) + 1)) - 1);
|
||||||
block_valid &= bits_to_keep;
|
|
||||||
block_invalid &= bits_to_keep;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
uint32_t block_page;
|
uint32_t block_page;
|
||||||
if (range_start == UINT32_MAX) {
|
if (range_start == UINT32_MAX) {
|
||||||
// Check if need to open a new range.
|
// Check if need to open a new range.
|
||||||
if (!xe::bit_scan_forward(block_invalid, &block_page)) {
|
if (!xe::bit_scan_forward(~block_valid, &block_page)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
range_start = (i << 6) + block_page;
|
range_start = (i << 6) + block_page;
|
||||||
} else {
|
} else {
|
||||||
// Check if need to close the range.
|
// Check if need to close the range.
|
||||||
if (!xe::bit_scan_forward(block_valid, &block_page)) {
|
// Ignore the valid pages before the beginning of the range.
|
||||||
|
uint64_t block_valid_from_start = block_valid;
|
||||||
|
if (i == (range_start >> 6)) {
|
||||||
|
block_valid_from_start &= ~((1ull << (range_start & 63)) - 1);
|
||||||
|
}
|
||||||
|
if (!xe::bit_scan_forward(block_valid_from_start, &block_page)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
upload_ranges_.push_back(
|
upload_ranges_.push_back(
|
||||||
std::make_pair(range_start, (i << 6) + block_page - range_start));
|
std::make_pair(range_start, (i << 6) + block_page - range_start));
|
||||||
|
// In the next interation within this block, consider this range valid
|
||||||
|
// since it has been queued for upload.
|
||||||
|
block_valid |= (1ull << block_page) - 1;
|
||||||
range_start = UINT32_MAX;
|
range_start = UINT32_MAX;
|
||||||
}
|
}
|
||||||
// There may be multiple ranges within a single block, so ignore the bits
|
|
||||||
// that have already been processed.
|
|
||||||
bits_to_keep = ~((1ull << block_page) - 1);
|
|
||||||
block_valid &= bits_to_keep;
|
|
||||||
block_invalid &= bits_to_keep;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (range_start != UINT32_MAX) {
|
if (range_start != UINT32_MAX) {
|
||||||
|
|
|
@ -200,7 +200,7 @@ class SharedMemory {
|
||||||
// persistently allocated vector).
|
// persistently allocated vector).
|
||||||
std::vector<UploadRange> upload_ranges_;
|
std::vector<UploadRange> upload_ranges_;
|
||||||
void GetRangesToUpload(uint32_t request_page_first,
|
void GetRangesToUpload(uint32_t request_page_first,
|
||||||
uint32_t request_page_count);
|
uint32_t request_page_last);
|
||||||
std::unique_ptr<ui::d3d12::UploadBufferPool> upload_buffer_pool_ = nullptr;
|
std::unique_ptr<ui::d3d12::UploadBufferPool> upload_buffer_pool_ = nullptr;
|
||||||
|
|
||||||
void TransitionBuffer(D3D12_RESOURCE_STATES new_state);
|
void TransitionBuffer(D3D12_RESOURCE_STATES new_state);
|
||||||
|
|
Loading…
Reference in New Issue