Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple Fences Associate with ONE Event #1840

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 41 additions & 8 deletions framework/decode/dx12_replay_consumer_base.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
** Copyright (c) 2021-2023 LunarG, Inc.
** Copyright (c) 2021-2023 Advanced Micro Devices, Inc. All rights reserved.
** Copyright (c) 2021-2024 Advanced Micro Devices, Inc. All rights reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and associated documentation files (the "Software"),
Expand Down Expand Up @@ -390,7 +390,7 @@ void Dx12ReplayConsumerBase::ApplyBatchedResourceInitInfo(
// 2. One ExecuteCommandLists could work for only one swapchain buffer.
// 3. The current back buffer index has to match the swapchain buffer.
// 4. After ExecuteCommandLists, the current back buffer index has to back init.
// 5. It shouldn't change resource states until all Presnt are done since Present require
// 5. It shouldn't change resource states until all Present are done since Present require
// D3D12_RESOURCE_STATE_PRESENT. The before_states supposes to be PRESENT.

// Although it has only one swapchain mostly, it probably has a plural in some cases.
Expand All @@ -404,7 +404,7 @@ void Dx12ReplayConsumerBase::ApplyBatchedResourceInitInfo(
auto swapchain = reinterpret_cast<IDXGISwapChain3*>(swapchain_info->object);
swapchain_infos[swapchain] = swapchain_extra_info;

for (auto &state : resource_info.second->before_states)
for (auto& state : resource_info.second->before_states)
{
if (state.states != D3D12_RESOURCE_STATE_PRESENT)
{
Expand Down Expand Up @@ -2425,6 +2425,7 @@ HRESULT Dx12ReplayConsumerBase::OverrideSetEventOnCompletion(DxObjectInfo* repla

auto replay_object = static_cast<ID3D12Fence*>(replay_object_info->object);
HANDLE event_object = GetEventObject(event_id, true);
IncreaseEventObjectRefcount(event_id);

auto replay_result = replay_object->SetEventOnCompletion(value, event_object);

Expand Down Expand Up @@ -3038,7 +3039,7 @@ void Dx12ReplayConsumerBase::DestroyActiveEvents()
{
for (const auto& entry : event_objects_)
{
CloseHandle(entry.second);
CloseHandle(entry.second.handle);
}

event_objects_.clear();
Expand Down Expand Up @@ -3177,8 +3178,8 @@ HANDLE Dx12ReplayConsumerBase::GetEventObject(uint64_t event_id, bool reset)
auto event_entry = event_objects_.find(event_id);
if (event_entry != event_objects_.end())
{
event_object = event_entry->second;
if (reset)
event_object = event_entry->second.handle;
if ((reset == true) && (event_entry->second.refcount == 0))
{
ResetEvent(event_object);
}
Expand All @@ -3188,7 +3189,8 @@ HANDLE Dx12ReplayConsumerBase::GetEventObject(uint64_t event_id, bool reset)
event_object = CreateEventA(nullptr, TRUE, FALSE, nullptr);
if (event_object != nullptr)
{
event_objects_[event_id] = event_object;
event_objects_[event_id].handle = event_object;
event_objects_[event_id].refcount = 0;
}
else
{
Expand All @@ -3199,11 +3201,42 @@ HANDLE Dx12ReplayConsumerBase::GetEventObject(uint64_t event_id, bool reset)
return event_object;
}

uint64_t Dx12ReplayConsumerBase::IncreaseEventObjectRefcount(uint64_t event_id)
{
auto event_entry = event_objects_.find(event_id);
if (event_entry != event_objects_.end())
{
++event_entry->second.refcount;
return event_entry->second.refcount;
}
return 0;
}

uint64_t Dx12ReplayConsumerBase::DecreaseEventObjectRefcount(HANDLE handle)
{
for each (auto& event in event_objects_)
{
if (event.second.handle == handle)
{
if (event.second.refcount > 0)
{
--const_cast<uint64_t&>(event.second.refcount);
}
return event.second.refcount;
}
}
return 0;
}

void Dx12ReplayConsumerBase::WaitForFenceEvent(format::HandleId fence_id, HANDLE event_object)
{
auto wait_result = WaitForSingleObject(event_object, kDefaultWaitTimeout);

if (wait_result == WAIT_TIMEOUT)
if (wait_result == WAIT_OBJECT_0)
{
DecreaseEventObjectRefcount(event_object);
}
else if (wait_result == WAIT_TIMEOUT)
{
GFXRECON_LOG_WARNING("Wait operation timed out for ID3D12Fence object %" PRId64 " synchronization", fence_id);
}
Expand Down
12 changes: 11 additions & 1 deletion framework/decode/dx12_replay_consumer_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -985,6 +985,12 @@ class Dx12ReplayConsumerBase : public Dx12Consumer
}
};

struct EventInfo
{
HANDLE handle;
uint64_t refcount;
};

IUnknown* GetCreateDeviceAdapter(DxObjectInfo* adapter_info);

void InitializeD3D12Device(HandlePointerDecoder<void*>* device);
Expand Down Expand Up @@ -1037,6 +1043,10 @@ class Dx12ReplayConsumerBase : public Dx12Consumer

HANDLE GetEventObject(uint64_t event_id, bool reset);

uint64_t IncreaseEventObjectRefcount(uint64_t event_id);

uint64_t DecreaseEventObjectRefcount(HANDLE handle);

void ReadDebugMessages();

void InitializeScreenshotHandler();
Expand Down Expand Up @@ -1081,7 +1091,7 @@ class Dx12ReplayConsumerBase : public Dx12Consumer
std::unordered_map<uint64_t, HWND> window_handles_;
std::unordered_map<uint64_t, MappedMemoryEntry> mapped_memory_;
std::unordered_map<uint64_t, void*> heap_allocations_;
std::unordered_map<uint64_t, HANDLE> event_objects_;
std::unordered_map<uint64_t, EventInfo> event_objects_;
std::function<void(const char*)> fatal_error_handler_;
Dx12DescriptorMap descriptor_map_;
graphics::Dx12GpuVaMap gpu_va_map_;
Expand Down
Loading