Skip to content

Commit 074cb2f

Browse files
committed
Move TemporaryFence/TemporaryCommandBuffer out of dump-resources into vulkan_temporary_objects.h/.cpp
- add CreateAndBegin(queue_family_index) overload - use GetDeviceQueue2-aware queue retrieval, check EndCommandBuffer/QueueSubmit results - use TemporaryCommandBuffer in ProcessSetSwapchainImageStateCommand
1 parent 3ae84e7 commit 074cb2f

6 files changed

Lines changed: 264 additions & 220 deletions

framework/decode/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ target_sources(gfxrecon_decode
276276
${CMAKE_CURRENT_LIST_DIR}/vulkan_swapchain.h
277277
${CMAKE_CURRENT_LIST_DIR}/vulkan_swapchain.cpp
278278
${CMAKE_CURRENT_LIST_DIR}/vulkan_swapchain_format.h
279+
${CMAKE_CURRENT_LIST_DIR}/vulkan_temporary_objects.h
280+
${CMAKE_CURRENT_LIST_DIR}/vulkan_temporary_objects.cpp
279281
${CMAKE_CURRENT_LIST_DIR}/vulkan_tracked_object_info.h
280282
${CMAKE_CURRENT_LIST_DIR}/vulkan_tracked_object_info_table.h
281283
${CMAKE_CURRENT_LIST_DIR}/vulkan_tracked_object_info.cpp

framework/decode/vulkan_replay_dump_resources_common.cpp

Lines changed: 0 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,77 +1395,6 @@ void CullDescriptors(const CommonObjectInfoTable& object_info_table_
13951395
}
13961396
}
13971397

1398-
VkResult TemporaryCommandBuffer::CreateAndBegin(graphics::FindQueueFamilyIndex_fp queue_finder_fp)
1399-
{
1400-
const uint32_t queue_index = queue_finder_fp(device_info.enabled_queue_family_flags);
1401-
GFXRECON_ASSERT(queue_index != VK_QUEUE_FAMILY_IGNORED);
1402-
1403-
const VkCommandPoolCreateInfo pool_create_info = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
1404-
nullptr,
1405-
VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
1406-
queue_index };
1407-
VkResult res = device_table.CreateCommandPool(device_info.handle, &pool_create_info, nullptr, &command_pool);
1408-
if (res != VK_SUCCESS)
1409-
{
1410-
GFXRECON_LOG_ERROR("%s() CreateCommandPool failed (%s)", __func__, util::ToString(res).c_str());
1411-
return res;
1412-
}
1413-
1414-
const VkCommandBufferAllocateInfo alloc_info = {
1415-
VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr, command_pool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1
1416-
};
1417-
res = device_table.AllocateCommandBuffers(device_info.handle, &alloc_info, &command_buffer);
1418-
if (res != VK_SUCCESS)
1419-
{
1420-
GFXRECON_LOG_ERROR("%s() AllocateCommandBuffers failed (%s)", __func__, util::ToString(res).c_str());
1421-
return res;
1422-
}
1423-
1424-
device_table.GetDeviceQueue(device_info.handle, queue_index, 0, &queue);
1425-
1426-
device_table.ResetCommandBuffer(command_buffer, VkCommandBufferResetFlagBits(0));
1427-
1428-
const VkCommandBufferBeginInfo begin_info = {
1429-
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, nullptr
1430-
};
1431-
1432-
res = device_table.BeginCommandBuffer(command_buffer, &begin_info);
1433-
if (res != VK_SUCCESS)
1434-
{
1435-
GFXRECON_LOG_ERROR("%s() BeginCommandBuffer failed (%s)", __func__, util::ToString(res).c_str());
1436-
return res;
1437-
}
1438-
1439-
return VK_SUCCESS;
1440-
}
1441-
1442-
VkResult TemporaryCommandBuffer::SubmitAndDestroy()
1443-
{
1444-
GFXRECON_ASSERT(command_buffer != VK_NULL_HANDLE);
1445-
GFXRECON_ASSERT(queue != VK_NULL_HANDLE);
1446-
GFXRECON_ASSERT(command_pool != VK_NULL_HANDLE);
1447-
1448-
TemporaryFence fence(device_info.handle, device_table);
1449-
1450-
device_table.EndCommandBuffer(command_buffer);
1451-
1452-
const VkSubmitInfo submit_info = {
1453-
VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &command_buffer, 0, nullptr
1454-
};
1455-
device_table.QueueSubmit(queue, 1, &submit_info, fence.handle);
1456-
1457-
VkResult res = fence.Wait();
1458-
if (res != VK_SUCCESS)
1459-
{
1460-
return res;
1461-
}
1462-
1463-
device_table.DestroyCommandPool(device_info.handle, command_pool, nullptr);
1464-
command_pool = VK_NULL_HANDLE;
1465-
1466-
return VK_SUCCESS;
1467-
}
1468-
14691398
static VkResult SerializeAccelerationStructure(AccelerationStructureDumpResourcesContext* acceleration_structure,
14701399
const VulkanDeviceInfo* device_info,
14711400
const graphics::VulkanDeviceTable& device_table,

framework/decode/vulkan_replay_dump_resources_common.h

Lines changed: 1 addition & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "decode/vulkan_replay_dump_resources_as.h"
3030
#include "decode/vulkan_replay_dump_resources_delegate_dumped_resources.h"
3131
#include "decode/vulkan_replay_options.h"
32+
#include "decode/vulkan_temporary_objects.h"
3233
#include "generated/generated_vulkan_dispatch_table.h"
3334
#include "generated/generated_vulkan_enum_to_string.h"
3435
#include "graphics/vulkan_util.h"
@@ -212,103 +213,6 @@ struct SecondaryIdentifiers
212213

213214
#define DEPTH_ATTACHMENT ~0
214215

215-
// Wrapper class for VkFence. Either holds an existing VkFence or creates and handles destruction of one
216-
struct TemporaryFence
217-
{
218-
TemporaryFence(VkFence other, VkDevice device, const graphics::VulkanDeviceTable& dt) :
219-
handle(other), parent_device(device), device_table(dt)
220-
{
221-
if (other == VK_NULL_HANDLE)
222-
{
223-
VkFenceCreateInfo fence_ci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 };
224-
const VkResult res = device_table.CreateFence(parent_device, &fence_ci, nullptr, &handle);
225-
needs_cleanup = (res == VK_SUCCESS);
226-
if (res != VK_SUCCESS)
227-
{
228-
GFXRECON_LOG_ERROR(
229-
"[%s:%u] CreateFence failed with %s", __FILE__, __LINE__, util::ToString(res).c_str());
230-
}
231-
}
232-
else
233-
{
234-
needs_cleanup = false;
235-
}
236-
}
237-
238-
TemporaryFence(VkDevice device, const graphics::VulkanDeviceTable& dt) : TemporaryFence(VK_NULL_HANDLE, device, dt)
239-
{}
240-
241-
VkResult Wait()
242-
{
243-
GFXRECON_ASSERT(parent_device != VK_NULL_HANDLE);
244-
GFXRECON_ASSERT(handle != VK_NULL_HANDLE);
245-
246-
// Wait a sensible amount of time (10 seconds) in case we did something that can cause the GPU to hang or crash.
247-
VkResult res = device_table.WaitForFences(parent_device, 1, &handle, VK_TRUE, 10000000000);
248-
if (res != VK_SUCCESS)
249-
{
250-
GFXRECON_LOG_ERROR("WaitForFences failed with %s", util::ToString(res).c_str());
251-
}
252-
253-
return res;
254-
}
255-
256-
VkResult Reset()
257-
{
258-
GFXRECON_ASSERT(parent_device != VK_NULL_HANDLE);
259-
GFXRECON_ASSERT(handle != VK_NULL_HANDLE);
260-
261-
VkResult res = device_table.ResetFences(parent_device, 1, &handle);
262-
if (res != VK_SUCCESS)
263-
{
264-
GFXRECON_LOG_ERROR("ResetFences failed with %s", util::ToString(res).c_str());
265-
}
266-
267-
return res;
268-
}
269-
270-
~TemporaryFence()
271-
{
272-
if (needs_cleanup)
273-
{
274-
GFXRECON_ASSERT(parent_device != VK_NULL_HANDLE);
275-
GFXRECON_ASSERT(handle != VK_NULL_HANDLE);
276-
277-
device_table.DestroyFence(parent_device, handle, nullptr);
278-
}
279-
}
280-
281-
VkFence handle;
282-
VkDevice parent_device;
283-
const graphics::VulkanDeviceTable& device_table;
284-
bool needs_cleanup;
285-
};
286-
287-
struct TemporaryCommandBuffer
288-
{
289-
TemporaryCommandBuffer(const VulkanDeviceInfo& dev_info, const graphics::VulkanDeviceTable& dev_table) :
290-
device_info(dev_info), device_table(dev_table)
291-
{}
292-
293-
~TemporaryCommandBuffer()
294-
{
295-
if (command_pool != VK_NULL_HANDLE)
296-
{
297-
device_table.DestroyCommandPool(device_info.handle, command_pool, nullptr);
298-
}
299-
};
300-
301-
VkResult CreateAndBegin(graphics::FindQueueFamilyIndex_fp queue_finder_fp);
302-
303-
VkResult SubmitAndDestroy();
304-
305-
const VulkanDeviceInfo& device_info{ nullptr };
306-
const graphics::VulkanDeviceTable& device_table{ nullptr };
307-
VkCommandPool command_pool{ VK_NULL_HANDLE };
308-
VkCommandBuffer command_buffer{ VK_NULL_HANDLE };
309-
VkQueue queue{ VK_NULL_HANDLE };
310-
};
311-
312216
GFXRECON_END_NAMESPACE(gfxrecon) GFXRECON_END_NAMESPACE(decode)
313217

314218
#endif /* GFXRECON_GENERATED_VULKAN_REPLAY_DUMP_RESOURCES_COMMON_H */
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*
2+
** Copyright (c) 2026 LunarG, Inc.
3+
**
4+
** Permission is hereby granted, free of charge, to any person obtaining a
5+
** copy of this software and associated documentation files (the "Software"),
6+
** to deal in the Software without restriction, including without limitation
7+
** the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+
** and/or sell copies of the Software, and to permit persons to whom the
9+
** Software is furnished to do so, subject to the following conditions:
10+
**
11+
** The above copyright notice and this permission notice shall be included in
12+
** all copies or substantial portions of the Software.
13+
**
14+
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19+
** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20+
** DEALINGS IN THE SOFTWARE.
21+
*/
22+
23+
#include "decode/vulkan_temporary_objects.h"
24+
25+
#include "decode/decoder_util.h"
26+
27+
GFXRECON_BEGIN_NAMESPACE(gfxrecon)
28+
GFXRECON_BEGIN_NAMESPACE(decode)
29+
30+
VkResult TemporaryCommandBuffer::CreateAndBegin(graphics::FindQueueFamilyIndex_fp queue_finder_fp)
31+
{
32+
const uint32_t queue_index = queue_finder_fp(device_info.enabled_queue_family_flags);
33+
GFXRECON_ASSERT(queue_index != VK_QUEUE_FAMILY_IGNORED);
34+
35+
return CreateAndBegin(queue_index);
36+
}
37+
38+
VkResult TemporaryCommandBuffer::CreateAndBegin(uint32_t queue_family_index)
39+
{
40+
const VkCommandPoolCreateInfo pool_create_info = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
41+
nullptr,
42+
VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
43+
queue_family_index };
44+
VkResult res = device_table.CreateCommandPool(device_info.handle, &pool_create_info, nullptr, &command_pool);
45+
if (res != VK_SUCCESS)
46+
{
47+
GFXRECON_LOG_ERROR("%s() CreateCommandPool failed (%s)", __func__, util::ToString(res).c_str());
48+
return res;
49+
}
50+
51+
const VkCommandBufferAllocateInfo alloc_info = {
52+
VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr, command_pool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1
53+
};
54+
res = device_table.AllocateCommandBuffers(device_info.handle, &alloc_info, &command_buffer);
55+
if (res != VK_SUCCESS)
56+
{
57+
GFXRECON_LOG_ERROR("%s() AllocateCommandBuffers failed (%s)", __func__, util::ToString(res).c_str());
58+
return res;
59+
}
60+
61+
queue = GetDeviceQueue(&device_table, &device_info, queue_family_index, 0);
62+
63+
device_table.ResetCommandBuffer(command_buffer, VkCommandBufferResetFlagBits(0));
64+
65+
const VkCommandBufferBeginInfo begin_info = {
66+
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, nullptr
67+
};
68+
69+
res = device_table.BeginCommandBuffer(command_buffer, &begin_info);
70+
if (res != VK_SUCCESS)
71+
{
72+
GFXRECON_LOG_ERROR("%s() BeginCommandBuffer failed (%s)", __func__, util::ToString(res).c_str());
73+
return res;
74+
}
75+
76+
return VK_SUCCESS;
77+
}
78+
79+
VkResult TemporaryCommandBuffer::SubmitAndDestroy()
80+
{
81+
GFXRECON_ASSERT(command_buffer != VK_NULL_HANDLE);
82+
GFXRECON_ASSERT(queue != VK_NULL_HANDLE);
83+
GFXRECON_ASSERT(command_pool != VK_NULL_HANDLE);
84+
85+
TemporaryFence fence(device_info.handle, device_table);
86+
87+
VkResult res = device_table.EndCommandBuffer(command_buffer);
88+
if (res != VK_SUCCESS)
89+
{
90+
GFXRECON_LOG_ERROR("%s() EndCommandBuffer failed (%s)", __func__, util::ToString(res).c_str());
91+
return res;
92+
}
93+
94+
const VkSubmitInfo submit_info = {
95+
VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &command_buffer, 0, nullptr
96+
};
97+
res = device_table.QueueSubmit(queue, 1, &submit_info, fence.handle);
98+
if (res != VK_SUCCESS)
99+
{
100+
GFXRECON_LOG_ERROR("%s() QueueSubmit failed (%s)", __func__, util::ToString(res).c_str());
101+
return res;
102+
}
103+
104+
res = fence.Wait();
105+
if (res != VK_SUCCESS)
106+
{
107+
return res;
108+
}
109+
110+
device_table.DestroyCommandPool(device_info.handle, command_pool, nullptr);
111+
command_pool = VK_NULL_HANDLE;
112+
113+
return VK_SUCCESS;
114+
}
115+
116+
GFXRECON_END_NAMESPACE(decode)
117+
GFXRECON_END_NAMESPACE(gfxrecon)

0 commit comments

Comments
 (0)