Skip to content

Commit

Permalink
Add Explorer example (#235)
Browse files Browse the repository at this point in the history
* Add Explorer example

* Fix typo
  • Loading branch information
spencer-lunarg authored Nov 14, 2023
1 parent 3f46812 commit 49dff33
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 1 deletion.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@ int SpirvReflectExample(const void* spirv_code, size_t spirv_nbytes)
A C++ wrapper is also provided.
## Building Examples
By adding `-DSPIRV_REFLECT_EXAMPLES=ON` in CMake you can see the use of the API used in action.
The `main_explorer.cpp` file is designed to allow an user to use their debugger of choice to breakpoint
and explorer the contents of the `SpvReflectShaderModule` object. Just build with `-DCMAKE_BUILD_TYPE=Debug`
and setup a debugger to run `./bin/explorer path/to/shader.spv`
## Building Self-Test Suite
SPIRV-Reflect uses [googletest](https://github.com/google/googletest) for self-testing.
Expand Down
17 changes: 16 additions & 1 deletion examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,19 @@ endif()
if(WIN32)
target_compile_definitions(hlsl_resource_types PRIVATE _CRT_SECURE_NO_WARNINGS)
set_target_properties(hlsl_resource_types PROPERTIES FOLDER "examples")
endif()
endif()

################################################################################
# explorer
################################################################################
add_executable(explorer ${CMAKE_CURRENT_SOURCE_DIR}/main_explorer.cpp ${COMMON_FILES} ${SPIRV_REFLECT_FILES})
target_include_directories(explorer PRIVATE ${CMAKE_SOURCE_DIR})
if (${VULKAN_DIR_FOUND})
target_compile_definitions(explorer PRIVATE SPIRV_REFLECT_HAS_VULKAN_H)
target_include_directories(explorer PRIVATE ${VULKAN_DIR}/include)
set_target_properties(explorer PROPERTIES CXX_STANDARD 11)
endif()
if(WIN32)
target_compile_definitions(explorer PRIVATE _CRT_SECURE_NO_WARNINGS)
set_target_properties(explorer PROPERTIES FOLDER "examples")
endif()
111 changes: 111 additions & 0 deletions examples/main_explorer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/* Copyright (c) 2023 LunarG, Inc.
*
* 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.
*/

#include <cassert>
#include <cstring>
#include <fstream>
#include <iostream>

#include "spirv_reflect.h"

// =================================================================================================
// PrintUsage()
// =================================================================================================
void PrintUsage() {
std::cout << "Usage: explorer path/to/SPIR-V/bytecode.spv\n"
<< "\tThis is used to set a breakpoint and explorer the API and "
"how to access info needed\n";
}

// =================================================================================================
// main()
// =================================================================================================
int main(int argn, char** argv) {
if (argn != 2) {
PrintUsage();
return EXIT_FAILURE;
} else if (std::string(argv[1]) == "--help") {
PrintUsage();
return EXIT_SUCCESS;
}
std::string input_spv_path = argv[1];

std::ifstream spv_ifstream(input_spv_path.c_str(), std::ios::binary);
if (!spv_ifstream.is_open()) {
std::cerr << "ERROR: could not open '" << input_spv_path
<< "' for reading\n";
return EXIT_FAILURE;
}

spv_ifstream.seekg(0, std::ios::end);
size_t size = static_cast<size_t>(spv_ifstream.tellg());
spv_ifstream.seekg(0, std::ios::beg);

std::vector<char> spv_data(size);
spv_ifstream.read(spv_data.data(), size);

SpvReflectShaderModule module = {};
SpvReflectResult result =
spvReflectCreateShaderModule(spv_data.size(), spv_data.data(), &module);
assert(result == SPV_REFLECT_RESULT_SUCCESS);

// Go through each enumerate to examine it
uint32_t count = 0;

result = spvReflectEnumerateDescriptorSets(&module, &count, NULL);
assert(result == SPV_REFLECT_RESULT_SUCCESS);
std::vector<SpvReflectDescriptorSet*> sets(count);
result = spvReflectEnumerateDescriptorSets(&module, &count, sets.data());
assert(result == SPV_REFLECT_RESULT_SUCCESS);

result = spvReflectEnumerateDescriptorBindings(&module, &count, NULL);
assert(result == SPV_REFLECT_RESULT_SUCCESS);
std::vector<SpvReflectDescriptorBinding*> bindings(count);
result =
spvReflectEnumerateDescriptorBindings(&module, &count, bindings.data());
assert(result == SPV_REFLECT_RESULT_SUCCESS);

result = spvReflectEnumerateInterfaceVariables(&module, &count, NULL);
assert(result == SPV_REFLECT_RESULT_SUCCESS);
std::vector<SpvReflectInterfaceVariable*> interface_variables(count);
result = spvReflectEnumerateInterfaceVariables(&module, &count,
interface_variables.data());
assert(result == SPV_REFLECT_RESULT_SUCCESS);

result = spvReflectEnumerateInputVariables(&module, &count, NULL);
assert(result == SPV_REFLECT_RESULT_SUCCESS);
std::vector<SpvReflectInterfaceVariable*> input_variables(count);
result = spvReflectEnumerateInputVariables(&module, &count,
input_variables.data());
assert(result == SPV_REFLECT_RESULT_SUCCESS);
result = spvReflectEnumerateOutputVariables(&module, &count, NULL);
assert(result == SPV_REFLECT_RESULT_SUCCESS);
std::vector<SpvReflectInterfaceVariable*> output_variables(count);
result = spvReflectEnumerateOutputVariables(&module, &count,
output_variables.data());
assert(result == SPV_REFLECT_RESULT_SUCCESS);

result = spvReflectEnumeratePushConstantBlocks(&module, &count, NULL);
assert(result == SPV_REFLECT_RESULT_SUCCESS);
std::vector<SpvReflectBlockVariable*> push_constant(count);
result = spvReflectEnumeratePushConstantBlocks(&module, &count,
push_constant.data());
assert(result == SPV_REFLECT_RESULT_SUCCESS);

// Can set a breakpoint here and explorer the various variables enumerated.
spvReflectDestroyShaderModule(&module);

return 0;
}

0 comments on commit 49dff33

Please sign in to comment.