Skip to content

Commit 4fe9b85

Browse files
committed
Adds custom dive vulkan consumer, annnotation processor
1 parent 9e151d5 commit 4fe9b85

20 files changed

+13658
-0
lines changed

cli/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ list(FILTER LIB_SRC_FILES EXCLUDE REGEX "main.cpp")
4646

4747
add_library(${PROJECT_NAME}_lib ${HDR_FILES} ${LIB_SRC_FILES} ${PM4_GENERATED_SRC_FILE} ${PM4_GENERATED_HDR_FILE})
4848
target_link_libraries(${PROJECT_NAME}_lib PRIVATE dive_core)
49+
target_link_libraries(${PROJECT_NAME}_lib PRIVATE gfxrecon_decode)
4950
target_include_directories(${PROJECT_NAME}_lib PRIVATE ${THIRDPARTY_DIRECTORY}/gfxreconstruct/framework)
5051

5152
add_executable(${PROJECT_NAME} ${HDR_FILES} "main.cpp")
@@ -75,6 +76,7 @@ endif()
7576
# Fuzz only on Clang for now.
7677
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
7778
add_executable(capture_fuzzer fuzz_main.cpp)
79+
target_include_directories(capture_fuzzer PRIVATE ${THIRDPARTY_DIRECTORY}/gfxreconstruct/framework)
7880
target_compile_definitions(capture_fuzzer PUBLIC -DDIVE_GUI_TOOL)
7981

8082
target_compile_options(capture_fuzzer
@@ -88,6 +90,7 @@ target_link_libraries(capture_fuzzer
8890
)
8991

9092
add_executable(capture_fuzzer_loader fuzz_main.cpp)
93+
target_include_directories(capture_fuzzer_loader PRIVATE ${THIRDPARTY_DIRECTORY}/gfxreconstruct/framework)
9194
target_compile_definitions(capture_fuzzer_loader PUBLIC -DDIVE_GUI_TOOL)
9295
target_compile_definitions(capture_fuzzer_loader PUBLIC -DDIVE_FUZZ_LOADER)
9396

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
Copyright 2025 Google LLC
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include "dive_annotation_processor.h"
18+
#include <cstdint>
19+
#include <iostream>
20+
#include <ostream>
21+
#include "decode/api_decoder.h"
22+
#include "util/logging.h"
23+
#include "util/output_stream.h"
24+
25+
DiveAnnotationProcessor::DiveAnnotationProcessor() {}
26+
27+
DiveAnnotationProcessor::~DiveAnnotationProcessor() {}
28+
29+
void DiveAnnotationProcessor::Destroy() {}
30+
31+
void DiveAnnotationProcessor::WriteBlockEnd(gfxrecon::util::DiveFunctionData function_data)
32+
{
33+
std::string function_name = function_data.GetFunctionName();
34+
35+
if (function_name == "vkQueueSubmit" || function_name == "vkQueueSubmit2")
36+
{
37+
std::unique_ptr<SubmitInfo> submit_ptr = std::make_unique<SubmitInfo>(function_name);
38+
39+
for (auto it = m_pre_submit_commands.begin(); it != m_pre_submit_commands.end(); ++it)
40+
{
41+
submit_ptr->AppendVkCmd(*it);
42+
}
43+
m_pre_submit_commands.clear();
44+
submit_ptr->SetCommandBufferCount(m_command_buffer_count);
45+
m_submits.push_back(std::move(submit_ptr));
46+
m_curr_submit = nullptr;
47+
m_command_buffer_count = 0;
48+
}
49+
else if (function_name.find("vkCmd") != std::string::npos ||
50+
function_name.find("vkBeginCommandBuffer") != std::string::npos)
51+
{
52+
// Don't include the vkEndCommandBuffer call.
53+
if (function_name.find("vkEndCommandBuffer") != std::string::npos)
54+
{
55+
return;
56+
}
57+
58+
VulkanCommandInfo vkCmd(function_data);
59+
60+
if (function_name.find("vkBeginCommandBuffer") != std::string::npos)
61+
{
62+
m_command_buffer_count++;
63+
}
64+
65+
if (m_curr_submit) // Check if the pointer is not null.
66+
{
67+
m_curr_submit->AppendVkCmd(vkCmd);
68+
}
69+
else
70+
{
71+
// No active submit, so buffer the command.
72+
m_pre_submit_commands.push_back(vkCmd);
73+
}
74+
}
75+
}
76+
77+
// Leave this function empty. It is necessary to avoid further changes to the gfxr file_processor.
78+
void DiveAnnotationProcessor::ProcessAnnotation(uint64_t block_index,
79+
gfxrecon::format::AnnotationType type,
80+
const std::string& label,
81+
const std::string& data)
82+
{
83+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
Copyright 2025 Google LLC
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
#pragma once
15+
16+
#include <cstdint>
17+
#include <optional>
18+
#include <string>
19+
#include "dive_core/stl_replacement.h"
20+
#include "third_party/gfxreconstruct/framework/decode/annotation_handler.h"
21+
#include "util/defines.h"
22+
#include "util/platform.h"
23+
24+
struct ApiCallInfo;
25+
26+
/// Manages writing
27+
class DiveAnnotationProcessor : public gfxrecon::decode::AnnotationHandler
28+
{
29+
public:
30+
struct VulkanCommandInfo
31+
{
32+
public:
33+
VulkanCommandInfo(std::string name, uint32_t index)
34+
{
35+
m_name = name;
36+
m_index = index;
37+
}
38+
VulkanCommandInfo(gfxrecon::util::DiveFunctionData data)
39+
{
40+
m_name = data.GetFunctionName();
41+
m_index = data.GetCmdBufferIndex();
42+
m_args = data.GetArgs();
43+
}
44+
const std::string GetVkCmdName() { return m_name; }
45+
uint32_t GetVkCmdIndex() { return m_index; }
46+
void SetCmdCount(uint32_t cmd_count) { m_cmd_count = cmd_count; }
47+
uint32_t GetCmdCount() { return m_cmd_count; }
48+
nlohmann::ordered_json GetArgs() { return m_args; }
49+
50+
private:
51+
std::string m_name;
52+
uint32_t m_index;
53+
uint32_t m_cmd_count; // Only used by vkBeginCommandBuffers
54+
nlohmann::ordered_json m_args;
55+
};
56+
57+
struct SubmitInfo
58+
{
59+
public:
60+
SubmitInfo() = default;
61+
SubmitInfo(std::string name) :
62+
m_name(name)
63+
{
64+
}
65+
std::string GetSubmitText() const { return m_name; }
66+
void SetCommandBufferCount(uint32_t cmd_buffer_count)
67+
{
68+
m_cmd_buffer_count = cmd_buffer_count;
69+
}
70+
uint32_t GetCommandBufferCount() const { return m_cmd_buffer_count; }
71+
const DiveVector<VulkanCommandInfo>& GetVkCmds() const { return vulkan_cmds; }
72+
void AppendVkCmd(VulkanCommandInfo vkCmd) { vulkan_cmds.push_back(vkCmd); }
73+
74+
private:
75+
std::string m_name;
76+
uint32_t m_cmd_buffer_count;
77+
DiveVector<VulkanCommandInfo> vulkan_cmds;
78+
};
79+
80+
DiveAnnotationProcessor();
81+
~DiveAnnotationProcessor();
82+
83+
void EndStream();
84+
void Destroy();
85+
bool IsValid() const;
86+
87+
/// Finalise the current block and stream it out.
88+
void WriteBlockEnd(gfxrecon::util::DiveFunctionData function_data) override;
89+
90+
void WriteMarker(const char* name, const std::string_view marker_type, uint64_t frame_number);
91+
92+
/// @brief Convert annotations, which are simple {type:enum, key:string, value:string} objects.
93+
virtual void ProcessAnnotation(uint64_t block_index,
94+
gfxrecon::format::AnnotationType type,
95+
const std::string& label,
96+
const std::string& data) override;
97+
98+
bool WriteBinaryFile(const std::string& filename, uint64_t data_size, const uint8_t* data);
99+
100+
inline void SetCurrentBlockIndex(uint64_t block_index) { block_index_ = block_index; }
101+
102+
DiveVector<std::unique_ptr<SubmitInfo>> getSubmits()
103+
{
104+
return std::move(m_submits);
105+
;
106+
}
107+
108+
private:
109+
DiveVector<std::unique_ptr<SubmitInfo>> m_submits;
110+
SubmitInfo* m_curr_submit = nullptr;
111+
uint32_t m_command_buffer_count = 0;
112+
std::vector<VulkanCommandInfo> m_pre_submit_commands; // Buffer for commands before a submit
113+
uint64_t block_index_;
114+
};

lrz_validator/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ set(LIB_SRC_FILES ${SRC_FILES})
4242
list(FILTER LIB_SRC_FILES EXCLUDE REGEX "main.cpp")
4343

4444
add_executable(${PROJECT_NAME} ${HDR_FILES} "main.cpp")
45+
target_include_directories(${PROJECT_NAME} PRIVATE ${THIRDPARTY_DIRECTORY}/gfxreconstruct/framework)
4546
target_link_libraries(${PROJECT_NAME} PRIVATE dive_core)
4647
target_include_directories(${PROJECT_NAME} PRIVATE ${THIRDPARTY_DIRECTORY}/gfxreconstruct/framework)
4748

third_party/gfxreconstruct/framework/decode/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,11 @@ target_sources(gfxrecon_decode
174174
${CMAKE_CURRENT_LIST_DIR}/vulkan_json_consumer_base.cpp
175175
${CMAKE_CURRENT_LIST_DIR}/marker_json_consumer.h
176176
${CMAKE_CURRENT_LIST_DIR}/metadata_json_consumer.h
177+
# GOOGLE: Include custom dive consumers.
178+
${CMAKE_CURRENT_LIST_DIR}/vulkan_dive_consumer_base.h
179+
${CMAKE_CURRENT_LIST_DIR}/vulkan_dive_consumer_base.cpp
180+
${CMAKE_CURRENT_LIST_DIR}/marker_dive_consumer.h
181+
${CMAKE_CURRENT_LIST_DIR}/metadata_dive_consumer.h
177182
${CMAKE_CURRENT_LIST_DIR}/vulkan_enum_util.h
178183
${CMAKE_CURRENT_LIST_DIR}/vulkan_feature_util.h
179184
${CMAKE_CURRENT_LIST_DIR}/vulkan_feature_util.cpp
@@ -237,6 +242,9 @@ target_sources(gfxrecon_decode
237242
${CMAKE_CURRENT_SOURCE_DIR}/../generated/generated_vulkan_enum_to_json.cpp
238243
${CMAKE_CURRENT_SOURCE_DIR}/../generated/generated_vulkan_json_consumer.h
239244
${CMAKE_CURRENT_SOURCE_DIR}/../generated/generated_vulkan_json_consumer.cpp
245+
# GOOGLE: Include the custom generated vulkan dive consumer.
246+
${CMAKE_CURRENT_SOURCE_DIR}/../generated/generated_vulkan_dive_consumer.h
247+
${CMAKE_CURRENT_SOURCE_DIR}/../generated/generated_vulkan_dive_consumer.cpp
240248
${CMAKE_CURRENT_SOURCE_DIR}/../generated/generated_vulkan_feature_util.cpp
241249
${CMAKE_CURRENT_SOURCE_DIR}/../generated/generated_vulkan_pnext_struct_decoder.cpp
242250
${CMAKE_CURRENT_SOURCE_DIR}/../generated/generated_vulkan_referenced_resource_consumer.h

third_party/gfxreconstruct/framework/decode/annotation_handler.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
#include "format/format.h"
2828
#include "util/defines.h"
29+
// GOOGLE: Include dive function data.
30+
#include "util/dive_function_data.h"
2931

3032
#include <string>
3133

@@ -41,6 +43,11 @@ class AnnotationHandler
4143
format::AnnotationType type,
4244
const std::string& label,
4345
const std::string& data) = 0;
46+
// GOOGLE: Adds function definitions.
47+
void WriteBlockStart();
48+
void WriteBlockEnd();
49+
// GOOGLE: Adds overridable function definition for custom dive annotation processor.
50+
virtual void WriteBlockEnd(util::DiveFunctionData function_data){}
4451
};
4552

4653
GFXRECON_END_NAMESPACE(decode)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
Copyright 2025 Google LLC
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
#ifndef GFXRECON_DECODE_MARKER_JSON_CONSUMER_BASE_H
15+
#define GFXRECON_DECODE_MARKER_JSON_CONSUMER_BASE_H
16+
17+
#include "util/defines.h"
18+
19+
GFXRECON_BEGIN_NAMESPACE(gfxrecon)
20+
GFXRECON_BEGIN_NAMESPACE(decode)
21+
22+
/// Template shim for turning markers into json using a JsonWriter pointed to by
23+
// a protected pointer called writer_ in a base class.
24+
template <class Base>
25+
class MarkerDiveConsumer : public Base
26+
{
27+
public:
28+
virtual void ProcessStateBeginMarker(uint64_t frame_number)
29+
{
30+
}
31+
virtual void ProcessStateEndMarker(uint64_t frame_number)
32+
{
33+
}
34+
35+
virtual void ProcessFrameEndMarker(uint64_t frame_number)
36+
{
37+
}
38+
};
39+
40+
GFXRECON_END_NAMESPACE(decode)
41+
GFXRECON_END_NAMESPACE(gfxrecon)
42+
43+
#endif // GFXRECON_DECODE_MARKER_JSON_CONSUMER_BASE_H

0 commit comments

Comments
 (0)