diff --git a/src/libs/dxmt-0.60/src/dxmt/dxmt_context.cpp b/src/libs/dxmt-0.60/src/dxmt/dxmt_context.cpp index 4e75c4ee60c9..78c3b05da9cc 100644 --- a/src/libs/dxmt-0.60/src/dxmt/dxmt_context.cpp +++ b/src/libs/dxmt-0.60/src/dxmt/dxmt_context.cpp @@ -37,11 +37,10 @@ ArgumentEncodingContext::ArgumentEncodingContext(CommandQueue &queue, WMT::Devic WMTResourceHazardTrackingModeUntracked; dummy_cbuffer_ = device.newBuffer(dummy_cbuffer_info_); std::memset(dummy_cbuffer_info_.memory.get(), 0, 65536); - cpu_buffer_ = malloc(kEncodingContextCPUHeapSize); + cpu_buffer_chunks_.emplace_back(); }; ArgumentEncodingContext::~ArgumentEncodingContext() { - free(cpu_buffer_); wsi::aligned_free(dummy_cbuffer_host_); }; @@ -679,6 +678,8 @@ ArgumentEncodingContext::currentFrameStatistics() { void ArgumentEncodingContext::$$setEncodingContext(uint64_t seq_id, uint64_t frame_id) { + current_buffer_chunk_ = 0; + cpu_buffer_ = cpu_buffer_chunks_[current_buffer_chunk_].ptr; cpu_buffer_offset_ = 0; seq_id_ = seq_id; frame_id_ = frame_id; @@ -919,6 +920,12 @@ ArgumentEncodingContext::flushCommands(WMT::CommandBuffer cmdbuf, uint64_t seqId cmdbuf.encodeSignalEvent(queue_.event, event_seq_id); + for (size_t i = cpu_buffer_chunks_.size() - 1; i > current_buffer_chunk_; i--) { + if (++cpu_buffer_chunks_[i].underused_times > kEncodingContextCPUHeapLifetime) { + cpu_buffer_chunks_.pop_back(); + } + } + return visibility_readback; } diff --git a/src/libs/dxmt-0.60/src/dxmt/dxmt_context.hpp b/src/libs/dxmt-0.60/src/dxmt/dxmt_context.hpp index 1848adf64b5f..4978b729b866 100644 --- a/src/libs/dxmt-0.60/src/dxmt/dxmt_context.hpp +++ b/src/libs/dxmt-0.60/src/dxmt/dxmt_context.hpp @@ -20,7 +20,8 @@ namespace dxmt { constexpr size_t kCommandChunkCPUHeapSize = 0x400000; constexpr size_t kCommandChunkGPUHeapSize = 0x400000; -constexpr size_t kEncodingContextCPUHeapSize = 0x1000000; +constexpr size_t kEncodingContextCPUHeapSize = 0x100000; +constexpr size_t kEncodingContextCPUHeapLifetime = 600; inline std::size_t align_forward_adjustment(const void *const ptr, const std::size_t &alignment) noexcept { @@ -584,13 +585,24 @@ class ArgumentEncodingContext { void * allocate_cpu_heap(size_t size, size_t alignment) { - std::size_t adjustment = align_forward_adjustment((void *)cpu_buffer_offset_, alignment); - auto aligned = cpu_buffer_offset_ + adjustment; - cpu_buffer_offset_ = aligned + size; - if (cpu_buffer_offset_ >= kEncodingContextCPUHeapSize) { - ERR(cpu_buffer_offset_, " - cpu argument heap overflow, expect error."); + assert(size < kEncodingContextCPUHeapSize); + for (;;) { + std::size_t adjustment = align_forward_adjustment((void *)cpu_buffer_offset_, alignment); + auto aligned = cpu_buffer_offset_ + adjustment; + cpu_buffer_offset_ = aligned + size; + if (unlikely(cpu_buffer_offset_ >= kEncodingContextCPUHeapSize)) { + current_buffer_chunk_++; + while (current_buffer_chunk_ >= cpu_buffer_chunks_.size()) { + cpu_buffer_chunks_.emplace_back(); + } + auto &chunk = cpu_buffer_chunks_[current_buffer_chunk_]; + chunk.underused_times = 0; + cpu_buffer_ = chunk.ptr; + cpu_buffer_offset_ = 0; + continue; + } + return ptr_add(cpu_buffer_, aligned); } - return ptr_add(cpu_buffer_, aligned); } template @@ -693,11 +705,33 @@ class ArgumentEncodingContext { EncoderData *encoder_current = nullptr; unsigned encoder_count_ = 0; - void *cpu_buffer_; - uint64_t cpu_buffer_offset_; uint64_t seq_id_; uint64_t frame_id_; + struct chunk { + void *ptr; + size_t underused_times; + + chunk() { + ptr = malloc(kEncodingContextCPUHeapSize); + underused_times = 0; + } + chunk(const chunk ©) = delete; + chunk(chunk &&move) { + ptr = move.ptr; + underused_times = move.underused_times; + move.ptr = nullptr; + }; + ~chunk() { + free(ptr); + ptr = nullptr; + } + }; + std::vector cpu_buffer_chunks_; + uint32_t current_buffer_chunk_ = 0; + void *cpu_buffer_; + uint64_t cpu_buffer_offset_; + VisibilityResultOffsetBumpState vro_state_; std::vector> pending_queries_; unsigned active_visibility_query_count_ = 0;