[D3D12] CP: Separate guest frame and non-frame submissions
This commit is contained in:
parent
d3b6f71ae1
commit
6e5a0ebf7b
|
@ -657,7 +657,7 @@ std::unique_ptr<xe::ui::RawImage> D3D12CommandProcessor::Capture() {
|
||||||
if (!readback_buffer) {
|
if (!readback_buffer) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
BeginFrame();
|
BeginSubmission(false);
|
||||||
PushTransitionBarrier(swap_texture_,
|
PushTransitionBarrier(swap_texture_,
|
||||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||||
D3D12_RESOURCE_STATE_COPY_SOURCE);
|
D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||||
|
@ -672,7 +672,7 @@ std::unique_ptr<xe::ui::RawImage> D3D12CommandProcessor::Capture() {
|
||||||
deferred_command_list_->CopyTexture(location_dest, location_source);
|
deferred_command_list_->CopyTexture(location_dest, location_source);
|
||||||
PushTransitionBarrier(swap_texture_, D3D12_RESOURCE_STATE_COPY_SOURCE,
|
PushTransitionBarrier(swap_texture_, D3D12_RESOURCE_STATE_COPY_SOURCE,
|
||||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||||
EndFrame();
|
EndSubmission(false);
|
||||||
AwaitAllSubmissionsCompletion();
|
AwaitAllSubmissionsCompletion();
|
||||||
D3D12_RANGE readback_range;
|
D3D12_RANGE readback_range;
|
||||||
readback_range.Begin = swap_texture_copy_footprint_.Offset;
|
readback_range.Begin = swap_texture_copy_footprint_.Offset;
|
||||||
|
@ -892,6 +892,9 @@ bool D3D12CommandProcessor::SetupContext() {
|
||||||
swap_texture_, &swap_srv_desc,
|
swap_texture_, &swap_srv_desc,
|
||||||
swap_texture_srv_descriptor_heap_->GetCPUDescriptorHandleForHeapStart());
|
swap_texture_srv_descriptor_heap_->GetCPUDescriptorHandleForHeapStart());
|
||||||
|
|
||||||
|
submission_open_ = false;
|
||||||
|
submission_frame_open_ = false;
|
||||||
|
|
||||||
pix_capture_requested_.store(false, std::memory_order_relaxed);
|
pix_capture_requested_.store(false, std::memory_order_relaxed);
|
||||||
pix_capturing_ = false;
|
pix_capturing_ = false;
|
||||||
|
|
||||||
|
@ -1030,7 +1033,7 @@ void D3D12CommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
||||||
SCOPE_profile_cpu_f("gpu");
|
SCOPE_profile_cpu_f("gpu");
|
||||||
|
|
||||||
// In case the swap command is the only one in the frame.
|
// In case the swap command is the only one in the frame.
|
||||||
BeginFrame();
|
BeginSubmission(true);
|
||||||
|
|
||||||
auto provider = GetD3D12Context()->GetD3D12Provider();
|
auto provider = GetD3D12Context()->GetD3D12Provider();
|
||||||
auto device = provider->GetDevice();
|
auto device = provider->GetDevice();
|
||||||
|
@ -1174,35 +1177,7 @@ void D3D12CommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EndFrame();
|
EndSubmission(true);
|
||||||
|
|
||||||
if (cache_clear_requested_) {
|
|
||||||
cache_clear_requested_ = false;
|
|
||||||
AwaitAllSubmissionsCompletion();
|
|
||||||
|
|
||||||
ui::d3d12::util::ReleaseAndNull(scratch_buffer_);
|
|
||||||
scratch_buffer_size_ = 0;
|
|
||||||
|
|
||||||
sampler_heap_pool_->ClearCache();
|
|
||||||
view_heap_pool_->ClearCache();
|
|
||||||
constant_buffer_pool_->ClearCache();
|
|
||||||
|
|
||||||
primitive_converter_->ClearCache();
|
|
||||||
|
|
||||||
pipeline_cache_->ClearCache();
|
|
||||||
|
|
||||||
render_target_cache_->ClearCache();
|
|
||||||
|
|
||||||
texture_cache_->ClearCache();
|
|
||||||
|
|
||||||
for (auto it : root_signatures_) {
|
|
||||||
it.second->Release();
|
|
||||||
}
|
|
||||||
root_signatures_.clear();
|
|
||||||
|
|
||||||
// TODO(Triang3l): Shared memory cache clear.
|
|
||||||
// shared_memory_->ClearCache();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Shader* D3D12CommandProcessor::LoadShader(ShaderType shader_type,
|
Shader* D3D12CommandProcessor::LoadShader(ShaderType shader_type,
|
||||||
|
@ -1290,7 +1265,7 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool new_frame = BeginFrame();
|
BeginSubmission(true);
|
||||||
|
|
||||||
// Set up the render targets - this may bind pipelines.
|
// Set up the render targets - this may bind pipelines.
|
||||||
if (!render_target_cache_->UpdateRenderTargets(pixel_shader)) {
|
if (!render_target_cache_->UpdateRenderTargets(pixel_shader)) {
|
||||||
|
@ -1708,7 +1683,7 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
||||||
memexport_range.base_address_dwords << 2, memexport_range_size);
|
memexport_range.base_address_dwords << 2, memexport_range_size);
|
||||||
readback_buffer_offset += memexport_range_size;
|
readback_buffer_offset += memexport_range_size;
|
||||||
}
|
}
|
||||||
EndFrame();
|
EndSubmission(false);
|
||||||
AwaitAllSubmissionsCompletion();
|
AwaitAllSubmissionsCompletion();
|
||||||
D3D12_RANGE readback_range;
|
D3D12_RANGE readback_range;
|
||||||
readback_range.Begin = 0;
|
readback_range.Begin = 0;
|
||||||
|
@ -1737,11 +1712,11 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12CommandProcessor::InitializeTrace() {
|
void D3D12CommandProcessor::InitializeTrace() {
|
||||||
BeginFrame();
|
BeginSubmission(false);
|
||||||
bool anySubmitted = false;
|
bool any_submitted = false;
|
||||||
anySubmitted |= shared_memory_->InitializeTraceSubmitDownloads();
|
any_submitted |= shared_memory_->InitializeTraceSubmitDownloads();
|
||||||
if (anySubmitted) {
|
if (any_submitted) {
|
||||||
EndFrame();
|
EndSubmission(false);
|
||||||
AwaitAllSubmissionsCompletion();
|
AwaitAllSubmissionsCompletion();
|
||||||
shared_memory_->InitializeTraceCompleteDownloads();
|
shared_memory_->InitializeTraceCompleteDownloads();
|
||||||
}
|
}
|
||||||
|
@ -1753,7 +1728,7 @@ bool D3D12CommandProcessor::IssueCopy() {
|
||||||
#if FINE_GRAINED_DRAW_SCOPES
|
#if FINE_GRAINED_DRAW_SCOPES
|
||||||
SCOPE_profile_cpu_f("gpu");
|
SCOPE_profile_cpu_f("gpu");
|
||||||
#endif // FINE_GRAINED_DRAW_SCOPES
|
#endif // FINE_GRAINED_DRAW_SCOPES
|
||||||
BeginFrame();
|
BeginSubmission(true);
|
||||||
uint32_t written_address, written_length;
|
uint32_t written_address, written_length;
|
||||||
if (!render_target_cache_->Resolve(shared_memory_.get(), texture_cache_.get(),
|
if (!render_target_cache_->Resolve(shared_memory_.get(), texture_cache_.get(),
|
||||||
memory_, written_address,
|
memory_, written_address,
|
||||||
|
@ -1771,7 +1746,7 @@ bool D3D12CommandProcessor::IssueCopy() {
|
||||||
deferred_command_list_->D3DCopyBufferRegion(
|
deferred_command_list_->D3DCopyBufferRegion(
|
||||||
readback_buffer, 0, shared_memory_buffer, written_address,
|
readback_buffer, 0, shared_memory_buffer, written_address,
|
||||||
written_length);
|
written_length);
|
||||||
EndFrame();
|
EndSubmission(false);
|
||||||
AwaitAllSubmissionsCompletion();
|
AwaitAllSubmissionsCompletion();
|
||||||
D3D12_RANGE readback_range;
|
D3D12_RANGE readback_range;
|
||||||
readback_range.Begin = 0;
|
readback_range.Begin = 0;
|
||||||
|
@ -1789,140 +1764,176 @@ bool D3D12CommandProcessor::IssueCopy() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3D12CommandProcessor::BeginFrame() {
|
void D3D12CommandProcessor::BeginSubmission(bool is_guest_command) {
|
||||||
if (submission_open_) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if FINE_GRAINED_DRAW_SCOPES
|
#if FINE_GRAINED_DRAW_SCOPES
|
||||||
SCOPE_profile_cpu_f("gpu");
|
SCOPE_profile_cpu_f("gpu");
|
||||||
#endif // FINE_GRAINED_DRAW_SCOPES
|
#endif // FINE_GRAINED_DRAW_SCOPES
|
||||||
|
|
||||||
submission_open_ = true;
|
if (!submission_open_) {
|
||||||
|
submission_open_ = true;
|
||||||
|
|
||||||
// Wait for a swap command list to become free.
|
// Wait for a swap command list to become free.
|
||||||
// Command list 0 is used when fence_current_value_ is 1, 4, 7...
|
// Command list 0 is used when fence_current_value_ is 1, 4, 7...
|
||||||
fence_completed_value_ = fence_->GetCompletedValue();
|
|
||||||
if (fence_completed_value_ + kQueuedFrames < fence_current_value_) {
|
|
||||||
fence_->SetEventOnCompletion(fence_current_value_ - kQueuedFrames,
|
|
||||||
fence_completion_event_);
|
|
||||||
WaitForSingleObject(fence_completion_event_, INFINITE);
|
|
||||||
fence_completed_value_ = fence_->GetCompletedValue();
|
fence_completed_value_ = fence_->GetCompletedValue();
|
||||||
|
if (fence_completed_value_ + kQueuedFrames < fence_current_value_) {
|
||||||
|
fence_->SetEventOnCompletion(fence_current_value_ - kQueuedFrames,
|
||||||
|
fence_completion_event_);
|
||||||
|
WaitForSingleObject(fence_completion_event_, INFINITE);
|
||||||
|
fence_completed_value_ = fence_->GetCompletedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start a new command list.
|
||||||
|
deferred_command_list_->Reset();
|
||||||
|
|
||||||
|
// Reset cached state of the command list.
|
||||||
|
ff_viewport_update_needed_ = true;
|
||||||
|
ff_scissor_update_needed_ = true;
|
||||||
|
ff_blend_factor_update_needed_ = true;
|
||||||
|
ff_stencil_ref_update_needed_ = true;
|
||||||
|
current_sample_positions_ = MsaaSamples::k1X;
|
||||||
|
current_cached_pipeline_ = nullptr;
|
||||||
|
current_external_pipeline_ = nullptr;
|
||||||
|
current_graphics_root_signature_ = nullptr;
|
||||||
|
current_graphics_root_up_to_date_ = 0;
|
||||||
|
current_view_heap_ = nullptr;
|
||||||
|
current_sampler_heap_ = nullptr;
|
||||||
|
primitive_topology_ = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
||||||
|
|
||||||
|
render_target_cache_->BeginSubmission();
|
||||||
|
|
||||||
|
primitive_converter_->BeginSubmission();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove outdated temporary buffers.
|
if (!submission_frame_open_) {
|
||||||
auto erase_buffers_end = buffers_for_deletion_.begin();
|
submission_frame_open_ = true;
|
||||||
while (erase_buffers_end != buffers_for_deletion_.end()) {
|
|
||||||
uint64_t upload_fence_value = erase_buffers_end->last_usage_fence_value;
|
// TODO(Triang3l): Move fence checking and command list releasing here.
|
||||||
if (upload_fence_value > fence_completed_value_) {
|
|
||||||
|
// Cleanup resources after checking the fence.
|
||||||
|
|
||||||
|
auto erase_buffers_end = buffers_for_deletion_.begin();
|
||||||
|
while (erase_buffers_end != buffers_for_deletion_.end()) {
|
||||||
|
if (erase_buffers_end->last_usage_fence_value > fence_completed_value_) {
|
||||||
|
++erase_buffers_end;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
erase_buffers_end->buffer->Release();
|
||||||
++erase_buffers_end;
|
++erase_buffers_end;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
erase_buffers_end->buffer->Release();
|
buffers_for_deletion_.erase(buffers_for_deletion_.begin(),
|
||||||
++erase_buffers_end;
|
erase_buffers_end);
|
||||||
}
|
|
||||||
buffers_for_deletion_.erase(buffers_for_deletion_.begin(), erase_buffers_end);
|
|
||||||
|
|
||||||
// Reset fixed-function state.
|
// Reset bindings that depend on the resources with lifetime tracked with
|
||||||
ff_viewport_update_needed_ = true;
|
// the fence.
|
||||||
ff_scissor_update_needed_ = true;
|
std::memset(current_float_constant_map_vertex_, 0,
|
||||||
ff_blend_factor_update_needed_ = true;
|
sizeof(current_float_constant_map_vertex_));
|
||||||
ff_stencil_ref_update_needed_ = true;
|
std::memset(current_float_constant_map_pixel_, 0,
|
||||||
|
sizeof(current_float_constant_map_pixel_));
|
||||||
|
cbuffer_bindings_system_.up_to_date = false;
|
||||||
|
cbuffer_bindings_float_vertex_.up_to_date = false;
|
||||||
|
cbuffer_bindings_float_pixel_.up_to_date = false;
|
||||||
|
cbuffer_bindings_bool_loop_.up_to_date = false;
|
||||||
|
cbuffer_bindings_fetch_.up_to_date = false;
|
||||||
|
draw_view_heap_index_ = ui::d3d12::DescriptorHeapPool::kHeapIndexInvalid;
|
||||||
|
draw_sampler_heap_index_ = ui::d3d12::DescriptorHeapPool::kHeapIndexInvalid;
|
||||||
|
texture_bindings_written_vertex_ = false;
|
||||||
|
texture_bindings_written_pixel_ = false;
|
||||||
|
samplers_written_vertex_ = false;
|
||||||
|
samplers_written_pixel_ = false;
|
||||||
|
|
||||||
// Since a new command list is being started, sample positions are reset to
|
constant_buffer_pool_->Reclaim(fence_completed_value_);
|
||||||
// centers.
|
view_heap_pool_->Reclaim(fence_completed_value_);
|
||||||
current_sample_positions_ = MsaaSamples::k1X;
|
sampler_heap_pool_->Reclaim(fence_completed_value_);
|
||||||
|
|
||||||
// Reset bindings, particularly because the buffers backing them are recycled.
|
pix_capturing_ =
|
||||||
current_cached_pipeline_ = nullptr;
|
pix_capture_requested_.exchange(false, std::memory_order_relaxed);
|
||||||
current_external_pipeline_ = nullptr;
|
if (pix_capturing_) {
|
||||||
current_graphics_root_signature_ = nullptr;
|
IDXGraphicsAnalysis* graphics_analysis =
|
||||||
current_graphics_root_up_to_date_ = 0;
|
GetD3D12Context()->GetD3D12Provider()->GetGraphicsAnalysis();
|
||||||
current_view_heap_ = nullptr;
|
if (graphics_analysis != nullptr) {
|
||||||
current_sampler_heap_ = nullptr;
|
graphics_analysis->BeginCapture();
|
||||||
std::memset(current_float_constant_map_vertex_, 0,
|
}
|
||||||
sizeof(current_float_constant_map_vertex_));
|
|
||||||
std::memset(current_float_constant_map_pixel_, 0,
|
|
||||||
sizeof(current_float_constant_map_pixel_));
|
|
||||||
cbuffer_bindings_system_.up_to_date = false;
|
|
||||||
cbuffer_bindings_float_vertex_.up_to_date = false;
|
|
||||||
cbuffer_bindings_float_pixel_.up_to_date = false;
|
|
||||||
cbuffer_bindings_bool_loop_.up_to_date = false;
|
|
||||||
cbuffer_bindings_fetch_.up_to_date = false;
|
|
||||||
draw_view_heap_index_ = ui::d3d12::DescriptorHeapPool::kHeapIndexInvalid;
|
|
||||||
draw_sampler_heap_index_ = ui::d3d12::DescriptorHeapPool::kHeapIndexInvalid;
|
|
||||||
texture_bindings_written_vertex_ = false;
|
|
||||||
texture_bindings_written_pixel_ = false;
|
|
||||||
samplers_written_vertex_ = false;
|
|
||||||
samplers_written_pixel_ = false;
|
|
||||||
primitive_topology_ = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
|
||||||
|
|
||||||
pix_capturing_ =
|
|
||||||
pix_capture_requested_.exchange(false, std::memory_order_relaxed);
|
|
||||||
if (pix_capturing_) {
|
|
||||||
IDXGraphicsAnalysis* graphics_analysis =
|
|
||||||
GetD3D12Context()->GetD3D12Provider()->GetGraphicsAnalysis();
|
|
||||||
if (graphics_analysis != nullptr) {
|
|
||||||
graphics_analysis->BeginCapture();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shared_memory_->BeginFrame();
|
||||||
|
|
||||||
|
texture_cache_->BeginFrame();
|
||||||
|
|
||||||
|
primitive_converter_->BeginFrame();
|
||||||
}
|
}
|
||||||
deferred_command_list_->Reset();
|
|
||||||
|
|
||||||
constant_buffer_pool_->Reclaim(fence_completed_value_);
|
|
||||||
view_heap_pool_->Reclaim(fence_completed_value_);
|
|
||||||
sampler_heap_pool_->Reclaim(fence_completed_value_);
|
|
||||||
|
|
||||||
shared_memory_->BeginFrame();
|
|
||||||
|
|
||||||
texture_cache_->BeginFrame();
|
|
||||||
|
|
||||||
render_target_cache_->BeginFrame();
|
|
||||||
|
|
||||||
primitive_converter_->BeginFrame();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3D12CommandProcessor::EndFrame() {
|
void D3D12CommandProcessor::EndSubmission(bool is_swap) {
|
||||||
if (!submission_open_) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto provider = GetD3D12Context()->GetD3D12Provider();
|
auto provider = GetD3D12Context()->GetD3D12Provider();
|
||||||
|
|
||||||
assert_false(scratch_buffer_used_);
|
if (is_swap && submission_frame_open_) {
|
||||||
|
texture_cache_->EndFrame();
|
||||||
pipeline_cache_->EndFrame();
|
|
||||||
|
|
||||||
render_target_cache_->EndFrame();
|
|
||||||
|
|
||||||
texture_cache_->EndFrame();
|
|
||||||
|
|
||||||
// Submit barriers now because resources the queued barriers are for may be
|
|
||||||
// destroyed between frames.
|
|
||||||
SubmitBarriers();
|
|
||||||
|
|
||||||
// Submit the command list.
|
|
||||||
uint32_t command_list_index =
|
|
||||||
uint32_t((fence_current_value_ + (kQueuedFrames - 1)) % kQueuedFrames);
|
|
||||||
auto current_command_list = command_lists_[command_list_index].get();
|
|
||||||
current_command_list->BeginRecording();
|
|
||||||
deferred_command_list_->Execute(current_command_list->GetCommandList(),
|
|
||||||
current_command_list->GetCommandList1());
|
|
||||||
current_command_list->Execute();
|
|
||||||
|
|
||||||
if (pix_capturing_) {
|
|
||||||
IDXGraphicsAnalysis* graphics_analysis = provider->GetGraphicsAnalysis();
|
|
||||||
if (graphics_analysis != nullptr) {
|
|
||||||
graphics_analysis->EndCapture();
|
|
||||||
}
|
|
||||||
pix_capturing_ = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
provider->GetDirectQueue()->Signal(fence_, fence_current_value_++);
|
if (submission_open_) {
|
||||||
submission_open_ = false;
|
assert_false(scratch_buffer_used_);
|
||||||
|
|
||||||
return true;
|
pipeline_cache_->EndSubmission();
|
||||||
|
|
||||||
|
render_target_cache_->EndSubmission();
|
||||||
|
|
||||||
|
// Submit barriers now because resources with the queued barriers may be
|
||||||
|
// destroyed between frames.
|
||||||
|
SubmitBarriers();
|
||||||
|
|
||||||
|
// Submit the command list.
|
||||||
|
uint32_t command_list_index =
|
||||||
|
uint32_t((fence_current_value_ + (kQueuedFrames - 1)) % kQueuedFrames);
|
||||||
|
auto current_command_list = command_lists_[command_list_index].get();
|
||||||
|
current_command_list->BeginRecording();
|
||||||
|
deferred_command_list_->Execute(current_command_list->GetCommandList(),
|
||||||
|
current_command_list->GetCommandList1());
|
||||||
|
current_command_list->Execute();
|
||||||
|
|
||||||
|
provider->GetDirectQueue()->Signal(fence_, fence_current_value_++);
|
||||||
|
|
||||||
|
submission_open_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_swap && submission_frame_open_) {
|
||||||
|
// Close the capture after submitting.
|
||||||
|
if (pix_capturing_) {
|
||||||
|
IDXGraphicsAnalysis* graphics_analysis = provider->GetGraphicsAnalysis();
|
||||||
|
if (graphics_analysis != nullptr) {
|
||||||
|
graphics_analysis->EndCapture();
|
||||||
|
}
|
||||||
|
pix_capturing_ = false;
|
||||||
|
}
|
||||||
|
submission_frame_open_ = false;
|
||||||
|
|
||||||
|
if (cache_clear_requested_) {
|
||||||
|
cache_clear_requested_ = false;
|
||||||
|
AwaitAllSubmissionsCompletion();
|
||||||
|
|
||||||
|
ui::d3d12::util::ReleaseAndNull(scratch_buffer_);
|
||||||
|
scratch_buffer_size_ = 0;
|
||||||
|
|
||||||
|
sampler_heap_pool_->ClearCache();
|
||||||
|
view_heap_pool_->ClearCache();
|
||||||
|
constant_buffer_pool_->ClearCache();
|
||||||
|
|
||||||
|
primitive_converter_->ClearCache();
|
||||||
|
|
||||||
|
pipeline_cache_->ClearCache();
|
||||||
|
|
||||||
|
render_target_cache_->ClearCache();
|
||||||
|
|
||||||
|
texture_cache_->ClearCache();
|
||||||
|
|
||||||
|
for (auto it : root_signatures_) {
|
||||||
|
it.second->Release();
|
||||||
|
}
|
||||||
|
root_signatures_.clear();
|
||||||
|
|
||||||
|
// TODO(Triang3l): Shared memory cache clear.
|
||||||
|
// shared_memory_->ClearCache();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12CommandProcessor::AwaitAllSubmissionsCompletion() {
|
void D3D12CommandProcessor::AwaitAllSubmissionsCompletion() {
|
||||||
|
|
|
@ -216,10 +216,18 @@ class D3D12CommandProcessor : public CommandProcessor {
|
||||||
const D3D12Shader* vertex_shader, const D3D12Shader* pixel_shader,
|
const D3D12Shader* vertex_shader, const D3D12Shader* pixel_shader,
|
||||||
RootExtraParameterIndices& indices_out);
|
RootExtraParameterIndices& indices_out);
|
||||||
|
|
||||||
// Returns true if a new frame was started.
|
// BeginSubmission and EndSubmission may be called at any time. If there's an
|
||||||
bool BeginFrame();
|
// open non-frame submission, BeginSubmission(true) will promote it to a
|
||||||
// Returns true if an open frame was ended.
|
// frame. EndSubmission(true) will close the frame no matter whether the
|
||||||
bool EndFrame();
|
// submission has already been closed.
|
||||||
|
|
||||||
|
// If is_guest_command is true, a new full frame - with full cleanup of
|
||||||
|
// resources and, if needed, starting capturing - is opened if pending (as
|
||||||
|
// opposed to simply resuming after mid-frame synchronization).
|
||||||
|
void BeginSubmission(bool is_guest_command);
|
||||||
|
// If is_swap is true, a full frame is closed - with, if needed, cache
|
||||||
|
// clearing and stopping capturing.
|
||||||
|
void EndSubmission(bool is_swap);
|
||||||
void AwaitAllSubmissionsCompletion();
|
void AwaitAllSubmissionsCompletion();
|
||||||
|
|
||||||
void UpdateFixedFunctionState(bool primitive_two_faced);
|
void UpdateFixedFunctionState(bool primitive_two_faced);
|
||||||
|
@ -315,6 +323,7 @@ class D3D12CommandProcessor : public CommandProcessor {
|
||||||
uint32_t readback_buffer_size_ = 0;
|
uint32_t readback_buffer_size_ = 0;
|
||||||
|
|
||||||
bool submission_open_ = false;
|
bool submission_open_ = false;
|
||||||
|
bool submission_frame_open_ = false;
|
||||||
|
|
||||||
std::atomic<bool> pix_capture_requested_ = false;
|
std::atomic<bool> pix_capture_requested_ = false;
|
||||||
bool pix_capturing_;
|
bool pix_capturing_;
|
||||||
|
|
|
@ -154,7 +154,7 @@ void PipelineCache::ClearCache() {
|
||||||
shader_map_.clear();
|
shader_map_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PipelineCache::EndFrame() {
|
void PipelineCache::EndSubmission() {
|
||||||
if (!creation_threads_.empty()) {
|
if (!creation_threads_.empty()) {
|
||||||
// Await creation of all queued pipelines.
|
// Await creation of all queued pipelines.
|
||||||
bool await_event = false;
|
bool await_event = false;
|
||||||
|
|
|
@ -42,7 +42,7 @@ class PipelineCache {
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void ClearCache();
|
void ClearCache();
|
||||||
|
|
||||||
void EndFrame();
|
void EndSubmission();
|
||||||
|
|
||||||
D3D12Shader* LoadShader(ShaderType shader_type, uint32_t guest_address,
|
D3D12Shader* LoadShader(ShaderType shader_type, uint32_t guest_address,
|
||||||
const uint32_t* host_address, uint32_t dword_count);
|
const uint32_t* host_address, uint32_t dword_count);
|
||||||
|
|
|
@ -142,28 +142,31 @@ void PrimitiveConverter::Shutdown() {
|
||||||
|
|
||||||
void PrimitiveConverter::ClearCache() { buffer_pool_->ClearCache(); }
|
void PrimitiveConverter::ClearCache() { buffer_pool_->ClearCache(); }
|
||||||
|
|
||||||
void PrimitiveConverter::BeginFrame() {
|
void PrimitiveConverter::BeginSubmission() {
|
||||||
uint64_t completed_fence_value = command_processor_->GetCompletedFenceValue();
|
|
||||||
// Got a command list now - upload and transition the static index buffer if
|
// Got a command list now - upload and transition the static index buffer if
|
||||||
// needed.
|
// needed.
|
||||||
if (static_ib_upload_ != nullptr) {
|
if (static_ib_upload_ && static_ib_upload_fence_value_ == UINT64_MAX) {
|
||||||
if (static_ib_upload_fence_value_ == UINT64_MAX) {
|
// Not uploaded yet - upload.
|
||||||
// Not uploaded yet - upload.
|
command_processor_->GetDeferredCommandList()->D3DCopyResource(
|
||||||
command_processor_->GetDeferredCommandList()->D3DCopyResource(
|
static_ib_, static_ib_upload_);
|
||||||
static_ib_, static_ib_upload_);
|
command_processor_->PushTransitionBarrier(
|
||||||
command_processor_->PushTransitionBarrier(
|
static_ib_, D3D12_RESOURCE_STATE_COPY_DEST,
|
||||||
static_ib_, D3D12_RESOURCE_STATE_COPY_DEST,
|
D3D12_RESOURCE_STATE_INDEX_BUFFER);
|
||||||
D3D12_RESOURCE_STATE_INDEX_BUFFER);
|
static_ib_upload_fence_value_ = command_processor_->GetCurrentFenceValue();
|
||||||
static_ib_upload_fence_value_ =
|
}
|
||||||
command_processor_->GetCurrentFenceValue();
|
}
|
||||||
} else if (completed_fence_value >= static_ib_upload_fence_value_) {
|
|
||||||
// Completely uploaded - release the upload buffer.
|
void PrimitiveConverter::BeginFrame() {
|
||||||
static_ib_upload_->Release();
|
uint64_t completed_fence_value = command_processor_->GetCompletedFenceValue();
|
||||||
static_ib_upload_ = nullptr;
|
|
||||||
}
|
if (static_ib_upload_ && static_ib_upload_fence_value_ != UINT64_MAX &&
|
||||||
|
completed_fence_value >= static_ib_upload_fence_value_) {
|
||||||
|
// Completely uploaded - release the upload buffer.
|
||||||
|
static_ib_upload_->Release();
|
||||||
|
static_ib_upload_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_pool_->Reclaim(completed_fence_value);
|
buffer_pool_->Reclaim(command_processor_->GetCompletedFenceValue());
|
||||||
|
|
||||||
converted_indices_cache_.clear();
|
converted_indices_cache_.clear();
|
||||||
memory_regions_used_ = 0;
|
memory_regions_used_ = 0;
|
||||||
|
|
|
@ -46,6 +46,7 @@ class PrimitiveConverter {
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void ClearCache();
|
void ClearCache();
|
||||||
|
|
||||||
|
void BeginSubmission();
|
||||||
void BeginFrame();
|
void BeginFrame();
|
||||||
|
|
||||||
// Returns the primitive type that the original type will be converted to.
|
// Returns the primitive type that the original type will be converted to.
|
||||||
|
|
|
@ -451,8 +451,8 @@ void RenderTargetCache::ClearCache() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderTargetCache::BeginFrame() {
|
void RenderTargetCache::BeginSubmission() {
|
||||||
// A frame does not always end in a resolve (for example, when memexport
|
// A submission does not always end in a resolve (for example, when memexport
|
||||||
// readback happens) or something else that would surely submit the UAV
|
// readback happens) or something else that would surely submit the UAV
|
||||||
// barrier, so we need to preserve the `current_` variables.
|
// barrier, so we need to preserve the `current_` variables.
|
||||||
if (!command_processor_->IsROVUsedForEDRAM()) {
|
if (!command_processor_->IsROVUsedForEDRAM()) {
|
||||||
|
@ -460,6 +460,8 @@ void RenderTargetCache::BeginFrame() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderTargetCache::EndSubmission() { UnbindRenderTargets(); }
|
||||||
|
|
||||||
bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) {
|
bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) {
|
||||||
// There are two kinds of render target binding updates in this implementation
|
// There are two kinds of render target binding updates in this implementation
|
||||||
// in case something has been changed - full and partial.
|
// in case something has been changed - full and partial.
|
||||||
|
@ -2116,8 +2118,6 @@ void RenderTargetCache::WriteEDRAMUint32UAVDescriptor(
|
||||||
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderTargetCache::EndFrame() { UnbindRenderTargets(); }
|
|
||||||
|
|
||||||
ColorRenderTargetFormat RenderTargetCache::GetBaseColorFormat(
|
ColorRenderTargetFormat RenderTargetCache::GetBaseColorFormat(
|
||||||
ColorRenderTargetFormat format) {
|
ColorRenderTargetFormat format) {
|
||||||
switch (format) {
|
switch (format) {
|
||||||
|
|
|
@ -255,7 +255,8 @@ class RenderTargetCache {
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void ClearCache();
|
void ClearCache();
|
||||||
|
|
||||||
void BeginFrame();
|
void BeginSubmission();
|
||||||
|
void EndSubmission();
|
||||||
// Called in the beginning of a draw call - may bind pipelines.
|
// Called in the beginning of a draw call - may bind pipelines.
|
||||||
bool UpdateRenderTargets(const D3D12Shader* pixel_shader);
|
bool UpdateRenderTargets(const D3D12Shader* pixel_shader);
|
||||||
// Returns the host-to-guest mappings and host formats of currently bound
|
// Returns the host-to-guest mappings and host formats of currently bound
|
||||||
|
@ -276,7 +277,6 @@ class RenderTargetCache {
|
||||||
// special.
|
// special.
|
||||||
void UnbindRenderTargets();
|
void UnbindRenderTargets();
|
||||||
void WriteEDRAMUint32UAVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle);
|
void WriteEDRAMUint32UAVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle);
|
||||||
void EndFrame();
|
|
||||||
|
|
||||||
// Totally necessary to rely on the base format - Too Human switches between
|
// Totally necessary to rely on the base format - Too Human switches between
|
||||||
// 2_10_10_10_FLOAT and 2_10_10_10_FLOAT_AS_16_16_16_16 every draw.
|
// 2_10_10_10_FLOAT and 2_10_10_10_FLOAT_AS_16_16_16_16 every draw.
|
||||||
|
|
|
@ -97,7 +97,6 @@ bool SharedMemory::Initialize() {
|
||||||
|
|
||||||
std::memset(heaps_, 0, sizeof(heaps_));
|
std::memset(heaps_, 0, sizeof(heaps_));
|
||||||
heap_count_ = 0;
|
heap_count_ = 0;
|
||||||
heap_creation_failed_ = false;
|
|
||||||
|
|
||||||
D3D12_DESCRIPTOR_HEAP_DESC buffer_descriptor_heap_desc;
|
D3D12_DESCRIPTOR_HEAP_DESC buffer_descriptor_heap_desc;
|
||||||
buffer_descriptor_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
|
buffer_descriptor_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
|
||||||
|
@ -168,7 +167,6 @@ void SharedMemory::Shutdown() {
|
||||||
|
|
||||||
void SharedMemory::BeginFrame() {
|
void SharedMemory::BeginFrame() {
|
||||||
upload_buffer_pool_->Reclaim(command_processor_->GetCompletedFenceValue());
|
upload_buffer_pool_->Reclaim(command_processor_->GetCompletedFenceValue());
|
||||||
heap_creation_failed_ = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedMemory::GlobalWatchHandle SharedMemory::RegisterGlobalWatch(
|
SharedMemory::GlobalWatchHandle SharedMemory::RegisterGlobalWatch(
|
||||||
|
@ -294,11 +292,6 @@ bool SharedMemory::MakeTilesResident(uint32_t start, uint32_t length) {
|
||||||
if (heaps_[i] != nullptr) {
|
if (heaps_[i] != nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (heap_creation_failed_) {
|
|
||||||
// Don't try to create a heap for every vertex buffer or texture in the
|
|
||||||
// current frame anymore if have failed at least once.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider();
|
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider();
|
||||||
auto device = provider->GetDevice();
|
auto device = provider->GetDevice();
|
||||||
auto direct_queue = provider->GetDirectQueue();
|
auto direct_queue = provider->GetDirectQueue();
|
||||||
|
@ -308,7 +301,6 @@ bool SharedMemory::MakeTilesResident(uint32_t start, uint32_t length) {
|
||||||
heap_desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
|
heap_desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
|
||||||
if (FAILED(device->CreateHeap(&heap_desc, IID_PPV_ARGS(&heaps_[i])))) {
|
if (FAILED(device->CreateHeap(&heap_desc, IID_PPV_ARGS(&heaps_[i])))) {
|
||||||
XELOGE("Shared memory: Failed to create a tile heap");
|
XELOGE("Shared memory: Failed to create a tile heap");
|
||||||
heap_creation_failed_ = true;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
++heap_count_;
|
++heap_count_;
|
||||||
|
|
|
@ -165,8 +165,6 @@ class SharedMemory {
|
||||||
ID3D12Heap* heaps_[kBufferSize >> kHeapSizeLog2] = {};
|
ID3D12Heap* heaps_[kBufferSize >> kHeapSizeLog2] = {};
|
||||||
// Number of the heaps currently resident, for profiling.
|
// Number of the heaps currently resident, for profiling.
|
||||||
uint32_t heap_count_ = 0;
|
uint32_t heap_count_ = 0;
|
||||||
// Whether creation of a heap has failed in the current frame.
|
|
||||||
bool heap_creation_failed_ = false;
|
|
||||||
|
|
||||||
// Log2 of system page size.
|
// Log2 of system page size.
|
||||||
uint32_t page_size_log2_;
|
uint32_t page_size_log2_;
|
||||||
|
|
Loading…
Reference in New Issue