This page provides a comprehensive guide on how to contribute to the Wisdom project.
Overview
We welcome contributions to the Wisdom project! Whether you're fixing bugs, adding features, improving documentation, or helping with testing, your contributions are valuable to the community.
Most of the time you can just submit an extension. There is a special implemntation pattern there, that is highly permissive. If the extension is implemented correctly for both backends, it will be included in the main repo and reworked to fit the main codebase. You can also submit a PR with a direct change to the main codebase, but it requires a bit more work, because of the need to follow the coding standards and design principles outlined in this document.
Before contributing, please familiarize yourself with our codebase structure and coding standards outlined below.
Getting Started
- Fork the repository on GitHub: https://github.com/Agrael1/Wisdom
- Clone your fork locally:
git clone https://github.com/your-username/Wisdom.git
- Create a feature branch:
git checkout -b feature/your-feature-name
- Set up the build environment following the Getting Started guide
- Make your changes following our coding standards
- Test your changes thoroughly
- Submit a pull request
Coding Standards and Best Practices
Code Style
The Wisdom project uses a custom clang-format configuration located in .clang-format at the root of the repository.
To format your code:
clang-format -i --style=file your-file.cpp
Or use your IDE's built-in clang-format support.
- Note
- The generator automatically formats generated files using clang-format during the build process. The repo formatting is also enforced in CI using GitHub Actions, so you don't have to worry about it.
Naming Conventions
Names follow Windows API conventions where applicable:
- Implementation Classes: PascalCase (e.g.,
DX12DeviceImpl, CommandQueue, DescriptorStorage)
- Variables and constants: snake_case (e.g.,
command_list, descriptor_heap)
- Defines: SCREAMING_SNAKE_CASE (e.g.,
WISDOM_VERSION)
- Everything else: should be generated by generator.
Implementation classes (e.g., DX12DeviceImpl) are internal and must be in *_types.hpp files under wis::impl namespace. They are consumed by the implementation classes, that are generated. You will get a lot of screams from compiler if something is wrong, so don't worry about it. Just follow the pattern and you will be fine. ;)
- Note
- I just prefer this style, it is not strictly enforced.
API Design Principles
- Result-based returns: Most functions return
wis::Result, otherwise they return the expected type directly. No exceptions or error codes.
- Manual lifetime management: All resources manage their own lifetime explicitly. Please always think about strict aliasing. There are functions provided, like
wis::from_handle, to help with this. Don't try to be smart and ignore them, it will only cause problems. The resources must be initialized with placement new and destroyed with the corresponding destroy function. No smart pointers or RAII wrappers in the main codebase, but feel free to use them in extensions.
- No virtual functions: Direct API calls for maximum performance, unless designing extension classes for device or instance.
- Platform abstraction: Code should work on both DirectX 12 and Vulkan backends, unless extensions are explicitly backend-specific.
Language Standards
- Primary: C++20 (required).
- Supported: C++23 features where available. If you want to use C++23 features, please ensure they are supported by all target compilers by using feature macros. Don't use
__cplusplus! It is unreliable on MSVC.
Build Requirements
CMake Requirements
- Minimum CMake version: 3.22
- Build system: Ninja (recommended)
- Presets: Use CMake presets for consistent builds, there are a lot of them, so check
CMakePresets.json for details. You can also create your own presets if needed.
Compiler Requirements
- Windows: MSVC 2022 or Clang 16+
- Linux: GCC 13+ or Clang 16+
- C++20 standard library: Required for
std::format (or use WISDOM_USE_FMT=ON)
Testing
Test Framework
The project uses Catch2 v3 Unit Test Framework for testing. Tests are located in the tests/ directory. Although graphics API is notoriously difficult to test, if possible, please write tests for any new features or bug fixes you implement. Tests should cover both DirectX 12 and Vulkan backends when applicable.
Running Tests
Tests have presets as well, so you can run them with CMake. For example, to run all tests in debug mode:
# Build the solution
cmake . --preset linux-gcc-debug
cmake --build --preset linux-gcc-debug
# Run tests
ctest --preset linux-gcc-debug
Writing Tests
- Place test files in
tests/basic/ or appropriate subdirectory
- Use Catch2 macros:
TEST_CASE, REQUIRE, CHECK
- Test both DirectX 12 and Vulkan backends when applicable
- Include proper cleanup and resource management
Example test structure:
#include <catch2/catch_test_macros.hpp>
#include <wisdom/wisdom.hpp>
TEST_CASE("your_test_name") {
wis::Result result;
auto factory = wis::CreateFactory(..., result);
REQUIRE(result.status == wis::Status::Ok);
REQUIRE(condition);
}
Documentation
Doxygen Documentation
- All public APIs must be documented with Doxygen comments
- Follow RFC 2119 guidelines for requirement levels (MUST, SHOULD, MAY)
- Use JavaDoc style and keywords appropriately
- Documentation is automatically generated and deployed to GitHub Pages
Documentation Generation
# Enable documentation build
cmake --preset x64-release -DWISDOM_BUILD_DOCS=ON
cmake --build --preset x64-release --target doc_doxygen
Submission Guidelines
Pull Requests
- Create descriptive commits: Use clear, concise commit messages
- Target the right branch: Submit PRs against the
master branch
- Include tests: New features should include appropriate tests
- Update documentation: Update relevant documentation pages
- Check CI: Ensure all GitHub Actions workflows pass
Pull Request Checklist
- [ ] Code follows the project's coding standards
- [ ] Code is formatted with clang-format (forced in CI)
- [ ] All tests pass locally
- [ ] New tests added for new functionality (if applicable)
- [ ] Documentation updated (if applicable)
- [ ] If breaking changes are introduced, they are clearly documented and justified. The PR will be marked with
vNext tag.
- [ ] Vulkan and DirectX 12 backends both work (if applicable)
Commit Message Format
Use descriptive commit messages that explain what and why:
feat: add descriptor buffer extension support
- Implement descriptor buffer for both DX12 and Vulkan
- Add comprehensive tests for descriptor operations
- Update documentation with usage examples
Fixes #123
Those can be generated by AI, but make sure to review and edit them for accuracy and clarity.
Continuous Integration
GitHub Actions
The project uses GitHub Actions for CI/CD with the following workflows:
- Linux build: Ubuntu with Vulkan backend
- Windows DirectX 12: MSVC with DirectX 12 backend
- Windows Vulkan: MSVC with Vulkan backend
- Windows Clang: Clang with Vulkan and C++20 modules
- Documentation: Auto-generated and deployed to GitHub Pages
- Release: Automated NuGet and GitHub releases
Build Matrix
All PRs are automatically tested against:
- Platforms: Windows, Linux
- Compilers: MSVC, Clang, GCC
- Graphics APIs: DirectX 12, Vulkan
- Build types: Debug, Release
Types of Contributions
Bug Fixes
- Report bugs using GitHub Issues
- Include minimal reproduction case
- Specify platform, compiler, and graphics API
- Test fixes on both graphics backends when possible
Feature Additions
- Discuss major features in GitHub Issues first
- Ensure cross-platform compatibility
- Follow existing API patterns
- Include comprehensive tests and documentation
Documentation Improvements
- Fix typos, clarify explanations
- Add usage examples
- Improve API documentation
- Update getting started guides
Platform Support
You can contribute by adding support for new platforms or improving existing platform integrations. This may involve:
- Add support for new platforms
- Improve existing platform integrations
- Update CMake configuration
- Ensure proper CI coverage
Community and Communication
License
By contributing to Wisdom, you agree that your contributions will be licensed under the same license as the project. Please see the LICENSE.txt file in the repository root for details.
- Note
- Thank you for your interest in contributing to Wisdom! Your contributions help make this library better for everyone.