Skip to content

Commit

Permalink
add spirv passes instead of having them in spirv-tools (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
rjodinchr authored Mar 8, 2024
1 parent a0c787a commit 7e9cc8a
Show file tree
Hide file tree
Showing 11 changed files with 994 additions and 75 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/presubmit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ jobs:
-DPERFETTO_TRACE_PROCESSOR_LIB="$(pwd)/third_party/perfetto/out/linux_clang_release/libtrace_processor.a" \
-DPERFETTO_CXX_CONFIG_INCLUDE_PATH="$(pwd)/third_party/perfetto/buildtools/libcxx_config" \
-DPERFETTO_CXX_SYSTEM_INCLUDE_PATH="$(pwd)/third_party/perfetto/buildtools/libcxx/include" \
-DSPIRV_HEADERS_INCLUDE_PATH="$(pwd)/third_party/spirv-tools/external/spirv-headers/include" \
-DSPIRV_TOOLS_BUILD_PATH="$(pwd)/third_party/spirv-tools/build" \
-DSPIRV_TOOLS_SOURCE_PATH="$(pwd)/third_party/spirv-tools" \
-DEXTRACTOR_NOSTDINCXX=1 \
-DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH};$(pwd)/install/lib/cmake/SPIRV-Tools-opt;$(pwd)/install/lib/cmake/SPIRV-Tools" \
-DCMAKE_CXX_COMPILER="$(which clang++)" \
Expand All @@ -85,6 +88,9 @@ jobs:
-DPERFETTO_TRACE_PROCESSOR_LIB="$(pwd)/third_party/perfetto/out/linux_clang_release/libtrace_processor.a" \
-DPERFETTO_CXX_CONFIG_INCLUDE_PATH="$(pwd)/third_party/perfetto/buildtools/libcxx_config" \
-DPERFETTO_CXX_SYSTEM_INCLUDE_PATH="$(pwd)/third_party/perfetto/buildtools/libcxx/include" \
-DSPIRV_HEADERS_INCLUDE_PATH="$(pwd)/third_party/spirv-tools/external/spirv-headers/include" \
-DSPIRV_TOOLS_BUILD_PATH="$(pwd)/third_party/spirv-tools/build" \
-DSPIRV_TOOLS_SOURCE_PATH="$(pwd)/third_party/spirv-tools" \
-DEXTRACTOR_NOSTDINCXX=1 \
-DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH};$(pwd)/install/lib/cmake/SPIRV-Tools-opt;$(pwd)/install/lib/cmake/SPIRV-Tools" \
-DCMAKE_CXX_COMPILER="$(which clang++)" \
Expand Down
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ endif()
if (NOT PERFETTO_INTERNAL_INCLUDE_PATH)
message(FATAL_ERROR "PERFETTO_INTERNAL_INCLUDE_PATH not defined")
endif()
if (NOT SPIRV_TOOLS_SOURCE_PATH)
message(FATAL_ERROR "SPIRV_TOOLS_SOURCE_PATH not defined")
endif()
if (NOT SPIRV_TOOLS_BUILD_PATH)
message(FATAL_ERROR "SPIRV_TOOLS_BUILD_PATH not defined")
endif()

find_package(SPIRV-Tools-opt)
message(STATUS "SPIRV-Tools-opt_LIBRARIES = '${SPIRV-Tools-opt_LIBRARIES}'")
Expand Down
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Using the `vulkan-shader-profiler-extractor` and `vulkan-shader-profiler-runner`

To compile it, please run:
```
cmake -B <build_dir> -S <path-to-vulkan-kernel-profiler> -DPERFETTO_SDK_PATH=<path-to-perfetto-sdk> -DPERFETTO_TRACE_PROCESSOR_LIB=<path-to-libtrace_processor.a> -DPERFETTO_INTERNAL_INCLUDE_PATH=<path-to-perfetto-include>
cmake -B <build_dir> -S <path-to-vulkan-kernel-profiler> -DPERFETTO_SDK_PATH=<path-to-perfetto-sdk> -DPERFETTO_TRACE_PROCESSOR_LIB=<path-to-libtrace_processor.a> -DPERFETTO_INTERNAL_INCLUDE_PATH=<path-to-perfetto-include> -DSPIRV_TOOLS_SOURCE_PATH=<path-to-spirv-tools-source-dir> -DSPIRV_TOOLS_BUILD_PATH=<path-to-spirv-tools-build-dir>
cmake --build <build_dir>
```

Expand All @@ -53,15 +53,19 @@ For a real life examples, have a look at:

## Build options

* `PERFETTO_SDK_PATH` (REQUIRED): path to [perfetto](https://github.com/google/perfetto) sdk (`vulkan-kernel-profiler` is looking for `PERFETTO_SDK_PATH/perfetto.cc` and `PERFETTO_SDK_PATH/perfetto.h`).
* `PERFETTO_TRACE_PROCESSOR_LIB` (REQUIRED): path to `libtrace_processor.a` produces by a perfetto build.
* `PERFETTO_INTERNAL_INCLUDE_PATH` (REQUIRED): path to perfetto internal include directory (`<perfetto>/include`), or where it is installed.
* REQUIRED:
* `PERFETTO_SDK_PATH`: path to [perfetto](https://github.com/google/perfetto) sdk (`vulkan-kernel-profiler` is looking for `PERFETTO_SDK_PATH/perfetto.cc` and `PERFETTO_SDK_PATH/perfetto.h`).
* `PERFETTO_TRACE_PROCESSOR_LIB`: path to `libtrace_processor.a` produces by a perfetto build.
* `PERFETTO_INTERNAL_INCLUDE_PATH`: path to perfetto internal include directory (`<perfetto>/include`), or where it is installed.
* `SPIRV_TOOLS_SOURCE_PATH`: path to [SPIRV-Tools](https://github.com/KhronosGroup/SPIRV-Tools) source directory (PR [#5512](https://github.com/KhronosGroup/SPIRV-Tools/pull/5512) is needed).
* `SPIRV_TOOLS_BUILD_PATH`: path to where [SPIRV-Tools](https://github.com/KhronosGroup/SPIRV-Tools) is built (not installed, just built).
* OPTIONAL:
* `PERFETTO_LIBRARY`: name of a perfetto library already available (avoid having to compile `perfetto.cc`).
* `PERFETTO_GEN_INCLUDE_PATH`: path to a a perfetto build (if not installed) `<perfetto>/out/release/gen/build_config`.
* `PERFETTO_CXX_CONFIG_INCLUDE_PATH`: path to perfetto buildtools config `<perfetto>/buildtools/libcxx_config`.
* `PERFETTO_CXX_SYSTEM_INCLUDE_PATH`: path to perfetto buildtools include `<perfetto>/buildtools/libcxx/include`.
* `EXTRACTOR_NOSTDINCXX`: build `vulkan-shader-profiler-extractor` with `-nostdinc++` to be able to link with some `libtrace_processor.a`.
* `SPIRV_HEADERS_INCLUDE_PATH`: path to [SPIRV-Headers](https://github.com/KhronosGroup/SPIRV-Headers) include directory (`<spirv-headers>/include`).
* `BACKEND`: [perfetto](https://github.com/google/perfetto) backend to use
* `InProcess` (default): the application will generate the traces ([perfetto documentation](https://perfetto.dev/docs/instrumentation/tracing-sdk#in-process-mode)). Build options and environment variables can be used to control the maximum size of traces and the destination file where the traces will be recorded.
* `System`: perfetto `traced` daemon will be responsible for generating the traces ([perfetto documentation](https://perfetto.dev/docs/instrumentation/tracing-sdk#system-mode)).
Expand Down
137 changes: 137 additions & 0 deletions common/common.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// Copyright 2024 The Vulkan Shader Profiler authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include <stdint.h>
#include <vulkan/vulkan.h>

namespace vksp {

struct vksp_push_constant {
uint32_t offset;
uint32_t size;
uint32_t stageFlags;
const char *pValues;
};

#define VKSP_DESCRIPTOR_TYPE_STORAGE_BUFFER_COUNTER_BITS (0xf0000000)
#define VKSP_DESCRIPTOR_TYPE_STORAGE_BUFFER_COUNTER_MASK (~VKSP_DESCRIPTOR_TYPE_STORAGE_BUFFER_COUNTER_BITS)
#define VKSP_DESCRIPTOR_TYPE_STORAGE_BUFFER_COUNTER \
(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER | VKSP_DESCRIPTOR_TYPE_STORAGE_BUFFER_COUNTER_BITS)
struct vksp_descriptor_set {
uint32_t ds;
uint32_t binding;
uint32_t type;
union {
struct {
uint32_t flags;
uint32_t queueFamilyIndexCount;
uint32_t sharingMode;
uint32_t size;
uint32_t usage;
uint32_t range;
uint32_t offset;
uint32_t memorySize;
uint32_t memoryType;
uint32_t bindOffset;
} buffer;
struct {
uint32_t imageLayout;
uint32_t imageFlags;
uint32_t imageType;
uint32_t format;
uint32_t width;
uint32_t height;
uint32_t depth;
uint32_t mipLevels;
uint32_t arrayLayers;
uint32_t samples;
uint32_t tiling;
uint32_t usage;
uint32_t sharingMode;
uint32_t queueFamilyIndexCount;
uint32_t initialLayout;
uint32_t aspectMask;
uint32_t baseMipLevel;
uint32_t levelCount;
uint32_t baseArrayLayer;
uint32_t layerCount;
uint32_t viewFlags;
uint32_t viewType;
uint32_t viewFormat;
uint32_t component_a;
uint32_t component_b;
uint32_t component_g;
uint32_t component_r;
uint32_t memorySize;
uint32_t memoryType;
uint32_t bindOffset;
} image;
struct {
uint32_t flags;
uint32_t magFilter;
uint32_t minFilter;
uint32_t mipmapMode;
uint32_t addressModeU;
uint32_t addressModeV;
uint32_t addressModeW;
union {
float fMipLodBias;
uint32_t uMipLodBias;
};
uint32_t anisotropyEnable;
union {
float fMaxAnisotropy;
uint32_t uMaxAnisotropy;
};
uint32_t compareEnable;
uint32_t compareOp;
union {
float fMinLod;
uint32_t uMinLod;
};
union {
float fMaxLod;
uint32_t uMaxLod;
};
uint32_t borderColor;
uint32_t unnormalizedCoordinates;
} sampler;
};
};

struct vksp_configuration {
const char *enabledExtensionNames;
uint32_t specializationInfoDataSize;
const char *specializationInfoData;
const char *shaderName;
const char *entryPoint;
uint32_t groupCountX;
uint32_t groupCountY;
uint32_t groupCountZ;
};

struct vksp_specialization_map_entry {
uint32_t constantID;
uint32_t offset;
uint32_t size;
};

struct vksp_counter {
uint32_t index;
const char *name;
};

}
16 changes: 14 additions & 2 deletions extractor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,24 @@
# limitations under the License.

add_library(vksp-spirv STATIC spirv.cpp)
target_include_directories(vksp-spirv PUBLIC ${SPIRV-Tools-opt_INCLUDE_DIRS})
target_link_libraries(vksp-spirv ${SPIRV-Tools-opt_LIBRARIES})
target_include_directories(vksp-spirv PUBLIC
${SPIRV-Tools-opt_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}
${SPIRV_TOOLS_SOURCE_PATH}
${SPIRV_TOOLS_BUILD_PATH}
)
if (SPIRV_HEADERS_INCLUDE_PATH)
target_include_directories(vksp-spirv PUBLIC ${SPIRV_HEADERS_INCLUDE_PATH})
endif()

add_executable(vulkan-shader-profiler-extractor extractor.cpp)
target_link_libraries(vulkan-shader-profiler-extractor ${PERFETTO_TRACE_PROCESSOR_LIB} vksp-spirv sqlite3)
target_include_directories(vulkan-shader-profiler-extractor PUBLIC ${Vulkan_INCLUDE_DIRS} ${PERFETTO_INTERNAL_INCLUDE_PATH})
target_include_directories(vulkan-shader-profiler-extractor PUBLIC
${Vulkan_INCLUDE_DIRS}
${PERFETTO_INTERNAL_INCLUDE_PATH}
${CMAKE_SOURCE_DIR}
)
if (PERFETTO_GEN_INCLUDE_PATH)
target_include_directories(vulkan-shader-profiler-extractor PUBLIC ${PERFETTO_GEN_INCLUDE_PATH})
endif()
Expand Down
31 changes: 16 additions & 15 deletions extractor/extractor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ std::unique_ptr<TraceProcessor> initialize_database()
}

bool get_dispatch_compute_and_commandBuffer_from_dispatchId(TraceProcessor *tp, uint64_t dispatchId, uint64_t &dispatch,
uint64_t &compute, uint64_t &commandBuffer, vksp_configuration &config)
uint64_t &compute, uint64_t &commandBuffer, vksp::vksp_configuration &config)
{
std::string query = "SELECT arg_set_id FROM args WHERE args.key = 'debug.dispatchId' AND args.int_value = "
+ std::to_string(dispatchId);
Expand Down Expand Up @@ -165,7 +165,7 @@ bool get_min_timestamp(TraceProcessor *tp, uint64_t commandBUffer, uint64_t max_
}

bool get_shader_and_device_from_compute(TraceProcessor *tp, uint64_t compute, std::string &shader,
std::vector<char> &shader_buffer, uint64_t &device, vksp_configuration &config)
std::vector<char> &shader_buffer, uint64_t &device, vksp::vksp_configuration &config)
{
GET_STR_VALUE(tp, compute, "debug.shader", config.shaderName);

Expand Down Expand Up @@ -222,7 +222,7 @@ bool get_extensions_from_device(TraceProcessor *tp, uint64_t device, const char
}

bool get_push_constants(TraceProcessor *tp, uint64_t commandBuffer, uint64_t max_timestamp, uint64_t min_timestamp,
std::vector<vksp_push_constant> &push_constants_vector)
std::vector<vksp::vksp_push_constant> &push_constants_vector)
{
std::string query = "SELECT arg_set_id, ts FROM slice WHERE slice.name = 'vkCmdPushConstants' AND slice.ts > "
+ std::to_string(min_timestamp) + " AND slice.ts < " + std::to_string(max_timestamp) + " AND "
Expand All @@ -234,7 +234,7 @@ bool get_push_constants(TraceProcessor *tp, uint64_t commandBuffer, uint64_t max
std::set<uint32_t> offsetWritten;
while (it.Next()) {
uint64_t arg_set_id = it.Get(0).AsLong();
vksp_push_constant pc;
vksp::vksp_push_constant pc;
GET_INT_VALUE(tp, arg_set_id, "debug.offset", pc.offset);
GET_INT_VALUE(tp, arg_set_id, "debug.size", pc.size);
GET_INT_VALUE(tp, arg_set_id, "debug.stageFlags", pc.stageFlags);
Expand All @@ -256,7 +256,7 @@ bool get_push_constants(TraceProcessor *tp, uint64_t commandBuffer, uint64_t max
}

bool get_buffer_descriptor_set(
TraceProcessor *tp, uint64_t write_arg_set_id, uint64_t write_timestamp, vksp_descriptor_set &ds)
TraceProcessor *tp, uint64_t write_arg_set_id, uint64_t write_timestamp, vksp::vksp_descriptor_set &ds)
{
uint64_t buffer;
GET_INT_VALUE(tp, write_arg_set_id, "debug.buffer", buffer);
Expand Down Expand Up @@ -304,7 +304,7 @@ bool get_buffer_descriptor_set(
}

bool get_image_descriptor_set(
TraceProcessor *tp, uint64_t write_arg_set_id, uint64_t write_timestamp, vksp_descriptor_set &ds)
TraceProcessor *tp, uint64_t write_arg_set_id, uint64_t write_timestamp, vksp::vksp_descriptor_set &ds)
{
uint64_t image_view;
GET_INT_VALUE(tp, write_arg_set_id, "debug.imageView", image_view);
Expand Down Expand Up @@ -384,7 +384,7 @@ bool get_image_descriptor_set(
}

bool get_sampler_descriptor_set(
TraceProcessor *tp, uint64_t write_arg_set_id, uint64_t write_timestamp, vksp_descriptor_set &ds)
TraceProcessor *tp, uint64_t write_arg_set_id, uint64_t write_timestamp, vksp::vksp_descriptor_set &ds)
{
uint64_t sampler;
GET_INT_VALUE(tp, write_arg_set_id, "debug.sampler", sampler);
Expand Down Expand Up @@ -418,7 +418,7 @@ bool get_sampler_descriptor_set(
}

bool get_descriptor_set(TraceProcessor *tp, uint64_t commandBuffer, uint64_t max_timestamp, uint64_t min_timestamp,
std::vector<vksp_descriptor_set> &descriptor_sets_vector)
std::vector<vksp::vksp_descriptor_set> &descriptor_sets_vector)
{
std::map<uint32_t, std::set<uint32_t>> dsSeen;
std::string query
Expand All @@ -432,7 +432,7 @@ bool get_descriptor_set(TraceProcessor *tp, uint64_t commandBuffer, uint64_t max
do {
uint64_t arg_set_id = it.Get(0).AsLong();
uint64_t bind_timestamp = it.Get(1).AsLong();
vksp_descriptor_set ds;
vksp::vksp_descriptor_set ds;

uint64_t dstSet;
{
Expand Down Expand Up @@ -493,7 +493,8 @@ bool get_descriptor_set(TraceProcessor *tp, uint64_t commandBuffer, uint64_t max
}

bool get_map_entries_from_cmd_buffer(TraceProcessor *tp, uint64_t commandBuffer, uint64_t max_timestamp,
uint64_t min_timestamp, std::vector<vksp_specialization_map_entry> &map_entry_vector, vksp_configuration &config)
uint64_t min_timestamp, std::vector<vksp::vksp_specialization_map_entry> &map_entry_vector,
vksp::vksp_configuration &config)
{
std::string query = "SELECT arg_set_id FROM slice WHERE slice.name = 'vkCmdBindPipeline' AND "
+ std::to_string(commandBuffer)
Expand All @@ -513,7 +514,7 @@ bool get_map_entries_from_cmd_buffer(TraceProcessor *tp, uint64_t commandBuffer,
EXECUTE_QUERY_NO_CHECK(it2, tp, query2);
while (it2.Next()) {
uint64_t arg_set_id = it2.Get(0).AsLong();
vksp_specialization_map_entry me;
vksp::vksp_specialization_map_entry me;
GET_INT_VALUE(tp, arg_set_id, "debug.constantID", me.constantID);
GET_INT_VALUE(tp, arg_set_id, "debug.offset", me.offset);
GET_INT_VALUE(tp, arg_set_id, "debug.size", me.size);
Expand Down Expand Up @@ -604,7 +605,7 @@ int main(int argc, char **argv)
CHECK(tp != nullptr, "Initialization failed");
PRINT("%s read with success", gInput.c_str());

vksp_configuration config;
vksp::vksp_configuration config;
uint64_t dispatch, compute, commandBuffer;
CHECK(get_dispatch_compute_and_commandBuffer_from_dispatchId(
tp.get(), gDispatchId, dispatch, compute, commandBuffer, config),
Expand Down Expand Up @@ -633,7 +634,7 @@ int main(int argc, char **argv)
CHECK(get_min_timestamp(tp.get(), commandBuffer, max_timestamp, min_timestamp), "Could not get min_timestamp");
PRINT("Min timestamp: %lu", min_timestamp);

std::vector<vksp_specialization_map_entry> map_entry_vector;
std::vector<vksp::vksp_specialization_map_entry> map_entry_vector;
CHECK(get_map_entries_from_cmd_buffer(
tp.get(), commandBuffer, max_timestamp, min_timestamp, map_entry_vector, config),
"Could not get map entries from command buffer");
Expand All @@ -646,15 +647,15 @@ int main(int argc, char **argv)
"Could not get features and extensions names from device");
PRINT("Extensions: '%s'", config.enabledExtensionNames);

std::vector<vksp_push_constant> push_constants_vector;
std::vector<vksp::vksp_push_constant> push_constants_vector;
CHECK(get_push_constants(tp.get(), commandBuffer, max_timestamp, min_timestamp, push_constants_vector),
"Could not get push_constants");
for (auto &pc : push_constants_vector) {
PRINT("push_constants: offset %u size %u stageFlags %u pValues %s", pc.offset, pc.size, pc.stageFlags,
pc.pValues);
}

std::vector<vksp_descriptor_set> descriptor_sets_vector;
std::vector<vksp::vksp_descriptor_set> descriptor_sets_vector;
CHECK(get_descriptor_set(tp.get(), commandBuffer, max_timestamp, min_timestamp, descriptor_sets_vector),
"Could not get descriptor_set");
for (auto &ds : descriptor_sets_vector) {
Expand Down
Loading

0 comments on commit 7e9cc8a

Please sign in to comment.