diff --git a/.clang-format b/.clang-format
new file mode 100644
index 00000000..00626b3e
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,189 @@
+# The style used for all options not specifically set in the configuration.
+BasedOnStyle: LLVM
+
+# The extra indent or outdent of access modifiers, e.g. public:.
+AccessModifierOffset: -4
+
+# Aligns escaped newlines as far left as possible
+AlignEscapedNewlines: Left
+
+# This will align the assignment operators of consecutive lines.
+AlignConsecutiveAssignments: Consecutive
+
+# Do not align the declaration names.
+AlignConsecutiveDeclarations: None
+
+# Align the bitfield in declarations
+AlignConsecutiveBitFields: Consecutive
+
+# If true, aligns trailing comments.
+AlignTrailingComments: true
+
+# Align operands when the expression is broken in multiple lines.
+AlignOperands: Align
+
+# Allow putting all parameters of a function declaration onto the next line even if BinPackParameters is false.
+AllowAllParametersOfDeclarationOnNextLine: false
+
+# Allows contracting simple braced statements to a single line.
+AllowShortBlocksOnASingleLine: false
+
+# If true, short case labels will be contracted to a single line.
+AllowShortCaseLabelsOnASingleLine: false
+
+# Dependent on the value, int f() { return 0; } can be put on a single line. Possible values: None, Inline, All.
+AllowShortFunctionsOnASingleLine: None
+
+# If true, if (a) return; can be put on a single line.
+AllowShortIfStatementsOnASingleLine: false
+
+# If true, while (true) continue; can be put on a single line.
+AllowShortLoopsOnASingleLine: false
+
+# If true, always break after function definition return types.
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+
+# If true, always break before multiline string literals.
+AlwaysBreakBeforeMultilineStrings: false
+
+# If true, always break after the template<...> of a template declaration.
+AlwaysBreakTemplateDeclarations: Yes
+
+# If false, a function call's arguments will either be all on the same line or will have one line each.
+BinPackArguments: true
+
+# If false, a function declaration's or function definition's parameters will either all be on the same line
+# or will have one line each.
+BinPackParameters: true
+
+# The way to wrap binary operators. Possible values: None, NonAssignment, All.
+BreakBeforeBinaryOperators: None
+
+# The brace breaking style to use. Possible values: Attach, Linux, Stroustrup, Allman, GNU.
+BreakBeforeBraces: Allman
+
+# If true, ternary operators will be placed after line breaks.
+BreakBeforeTernaryOperators: false
+
+# Always break constructor initializers before commas and align the commas with the colon.
+BreakConstructorInitializers: BeforeComma
+
+# The column limit. A column limit of 0 means that there is no column limit.
+ColumnLimit: 120
+
+# A regular expression that describes comments with special meaning, which should not be split into lines or otherwise changed.
+CommentPragmas: "^ *"
+
+# If the constructor initializers don't fit on a line, put each initializer on its own line.
+PackConstructorInitializers: CurrentLine
+
+# The number of characters to use for indentation of constructor initializer lists.
+ConstructorInitializerIndentWidth: 4
+
+# Indent width for line continuations.
+ContinuationIndentWidth: 4
+
+# If true, format braced lists as best suited for C++11 braced lists.
+Cpp11BracedListStyle: true
+
+# Disables formatting at all.
+DisableFormat: false
+
+# Indent case labels one level from the switch statement.
+# When false, use the same indentation level as for the switch statement.
+# Switch statement body is always indented one level more than case labels.
+IndentCaseLabels: false
+
+# The number of columns to use for indentation.
+IndentWidth: 4
+
+# Indent if a function definition or declaration is wrapped after the type.
+IndentWrappedFunctionNames: false
+
+# If true, empty lines at the start of blocks are kept.
+KeepEmptyLinesAtTheStartOfBlocks: true
+
+# Language, this format style is targeted at. Possible values: None, Cpp, Java, JavaScript, Proto.
+Language: Cpp
+
+# The maximum number of consecutive empty lines to keep.
+MaxEmptyLinesToKeep: 1
+
+# The indentation used for namespaces. Possible values: None, Inner, All.
+NamespaceIndentation: None
+
+# The penalty for breaking a function call after "call(".
+PenaltyBreakBeforeFirstCallParameter: 19
+
+# The penalty for each line break introduced inside a comment.
+PenaltyBreakComment: 300
+
+# The penalty for breaking before the first <<.
+PenaltyBreakFirstLessLess: 400
+
+# The penalty for each line break introduced inside a string literal.
+PenaltyBreakString: 1000
+
+# The penalty for each character outside of the column limit.
+PenaltyExcessCharacter: 1000000
+
+# Penalty for putting the return type of a function onto its own line.
+PenaltyReturnTypeOnItsOwnLine: 1000000000
+
+# Pointer and reference alignment style. Possible values: Left, Right, Middle.
+PointerAlignment: Right
+
+# Do not sort includes, many generated headers don't appropriately include what they rely on.
+SortIncludes: Never
+
+# If true, a space may be inserted after C style casts.
+SpaceAfterCStyleCast: false
+
+# If false, spaces will be removed before assignment operators.
+SpaceBeforeAssignmentOperators: true
+
+# Defines in which cases to put a space before opening parentheses. Possible values: Never, ControlStatements, Always.
+SpaceBeforeParens: ControlStatements
+
+# If true, spaces may be inserted into '()'.
+SpaceInEmptyParentheses: false
+
+# The number of spaces before trailing line comments (// - comments).
+SpacesBeforeTrailingComments: 1
+
+# If true, spaces will be inserted after '<' and before '>' in template argument lists.
+SpacesInAngles: false
+
+# If true, spaces may be inserted into C style casts.
+SpacesInCStyleCastParentheses: false
+
+# If true, spaces are inserted inside container literals (e.g. ObjC and Javascript array and dict literals).
+SpacesInContainerLiterals: false
+
+# If true, spaces will be inserted after '(' and before ')'.
+SpacesInParentheses: false
+
+# If true, spaces will be inserted after '[' and before ']'.
+SpacesInSquareBrackets: false
+
+# Format compatible with this standard, e.g. use A > instead of A> for LS_Cpp03. Possible values: Cpp03, Cpp11, Auto.
+Standard: Cpp11
+
+# The number of columns used for tab stops.
+TabWidth: 4
+
+# The way to use tab characters in the resulting file. Possible values: Never, ForIndentation, Always.
+UseTab: Never
+
+# Support formatting other languages too, mostly using default configs
+---
+Language: Java
+IndentWidth: 4
+---
+Language: Json
+IndentWidth: 4
+---
+Language: ObjC
+IndentWidth: 4
+BreakBeforeBraces: Allman
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 34c47419..6d06663a 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -14,6 +14,69 @@ env:
BUILD_JOBS: 16
jobs:
+ check-coding-style:
+ runs-on: ubuntu-22.04
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+
+ - name: Set up Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.x'
+
+ - name: Install pre-commit
+ run: pip install pre-commit
+
+ - name: Install clang-format
+ run: |
+ sudo apt update
+ sudo apt install --assume-yes clang-format
+
+ - name: Run pre-commit
+ run: |
+ # Determine the base reference for comparison
+ if [ "${{ github.event_name }}" == "pull_request" ]; then
+ BASE_REF="origin/${{ github.event.pull_request.base.ref }}"
+ else
+ BASE_REF="origin/main"
+ fi
+
+ echo "Running pre-commit from $BASE_REF to HEAD"
+ pre-commit run --from-ref $BASE_REF --to-ref HEAD
+
+ check-commit-messages:
+ runs-on: ubuntu-22.04
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+
+ - name: Set up Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.x'
+
+ - name: Install gitlint
+ run: pip install gitlint
+
+ - name: Run gitlint
+ run: |
+ # Determine the base reference for comparison
+ if [ "${{ github.event_name }}" == "pull_request" ]; then
+ BASE_REF="origin/${{ github.event.pull_request.base.ref }}"
+ else
+ BASE_REF="origin/main"
+ fi
+
+ echo "Running gitlint from $BASE_REF to HEAD"
+ gitlint --commits $BASE_REF..HEAD
+
Vulkan-Video-Samples-linux:
strategy:
matrix:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 00000000..ab14dbce
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,11 @@
+repos:
+ - repo: local
+ hooks:
+ - id: check-code-format
+ name: Check C/C++ code formatting
+ entry: python scripts/check_code_format.py
+ language: system
+ files: \.(c|cc|cxx|cpp|h|hpp)$
+ exclude: ^include/vulkan/
+ pass_filenames: false
+ always_run: false
\ No newline at end of file
diff --git a/scripts/check_code_format.py b/scripts/check_code_format.py
new file mode 100644
index 00000000..c0185223
--- /dev/null
+++ b/scripts/check_code_format.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python3
+
+# Copyright (c) 2017 Google 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.
+#
+# Script to determine if source code in Pull Request is properly formatted.
+# Exits with non 0 exit code if formatting is needed.
+#
+# This script assumes to be invoked at the project root directory.
+
+import subprocess
+import sys
+import os
+import re
+
+# Color codes for terminal output
+class Colors:
+ RED = '\033[0;31m'
+ GREEN = '\033[0;32m'
+ NC = '\033[0m' # No Color
+
+def run_command(cmd, capture_output=True):
+ """Run a shell command and return the result."""
+ try:
+ result = subprocess.run(cmd, shell=True, capture_output=capture_output,
+ text=True, check=False)
+ return result.returncode, result.stdout, result.stderr
+ except Exception as e:
+ print(f"Error running command '{cmd}': {e}")
+ return 1, "", str(e)
+
+def get_files_to_check():
+ """Get list of C/C++ files to check formatting for."""
+ # Get files changed compared to master
+ returncode, stdout, stderr = run_command("git diff --name-only master")
+ if returncode != 0:
+ print(f"Error getting git diff: {stderr}")
+ return []
+
+ files = stdout.strip().split('\n') if stdout.strip() else []
+
+ # Filter for C/C++ files, excluding vulkan headers
+ cpp_extensions = re.compile(r'.*\.(cpp|cc|c\+\+|cxx|c|h|hpp)$')
+ vulkan_include = re.compile(r'^include/vulkan')
+
+ filtered_files = []
+ for file in files:
+ if file and cpp_extensions.match(file) and not vulkan_include.match(file):
+ filtered_files.append(file)
+
+ return filtered_files
+
+def check_formatting(files):
+ """Check formatting of specified files using clang-format-diff.py."""
+ if not files:
+ return True, ""
+
+ files_str = ' '.join(files)
+ cmd = f"git diff -U0 master -- {files_str} | python ./scripts/clang-format-diff.py -p1 -style=file"
+
+ returncode, stdout, stderr = run_command(cmd)
+ if returncode != 0:
+ print(f"Error running clang-format-diff: {stderr}")
+ return False, stderr
+
+ return stdout.strip() == "", stdout
+
+def main():
+ """Main function to check code formatting."""
+ # Change to script directory's parent (project root)
+ script_dir = os.path.dirname(os.path.abspath(__file__))
+ project_root = os.path.dirname(script_dir)
+ os.chdir(project_root)
+
+ files_to_check = get_files_to_check()
+
+ if not files_to_check:
+ print(f"{Colors.GREEN}No source code to check for formatting.{Colors.NC}")
+ return 0
+
+ print(f"Checking formatting for files: {', '.join(files_to_check)}")
+
+ is_formatted, format_output = check_formatting(files_to_check)
+
+ if is_formatted:
+ print(f"{Colors.GREEN}All source code in PR properly formatted.{Colors.NC}")
+ return 0
+ else:
+ print(f"{Colors.RED}Found formatting errors!{Colors.NC}")
+ print(format_output)
+ return 1
+
+if __name__ == "__main__":
+ sys.exit(main())
\ No newline at end of file
diff --git a/scripts/check_code_format.sh b/scripts/check_code_format.sh
deleted file mode 100644
index dde43794..00000000
--- a/scripts/check_code_format.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/bash
-# Copyright (c) 2017 Google 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.
-#
-# Script to determine if source code in Pull Request is properly formatted.
-# Exits with non 0 exit code if formatting is needed.
-#
-# This script assumes to be invoked at the project root directory.
-
-RED='\033[0;31m'
-GREEN='\033[0;32m'
-NC='\033[0m' # No Color
-
-FILES_TO_CHECK=$(git diff --name-only master | grep -v -E "^include/vulkan" | grep -E ".*\.(cpp|cc|c\+\+|cxx|c|h|hpp)$")
-
-if [ -z "${FILES_TO_CHECK}" ]; then
- echo -e "${GREEN}No source code to check for formatting.${NC}"
- exit 0
-fi
-
-FORMAT_DIFF=$(git diff -U0 master -- ${FILES_TO_CHECK} | python ./scripts/clang-format-diff.py -p1 -style=file)
-
-if [ -z "${FORMAT_DIFF}" ]; then
- echo -e "${GREEN}All source code in PR properly formatted.${NC}"
- exit 0
-else
- echo -e "${RED}Found formatting errors!${NC}"
- echo "${FORMAT_DIFF}"
- exit 1
-fi
diff --git a/scripts/clang-format-diff.py b/scripts/clang-format-diff.py
new file mode 100755
index 00000000..3e08c9c9
--- /dev/null
+++ b/scripts/clang-format-diff.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python3
+#===- clang-format-diff.py - ClangFormat Diff Utility -------*- python -*--===#
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+#===------------------------------------------------------------------------===#
+
+"""
+ClangFormat Diff Utility
+v1.0
+
+This script reads a unified diff from stdin and reformats all the changed
+lines. This is useful to reformat all the lines touched by a specific patch.
+Example usage for git users:
+
+ git diff -U0 --no-color HEAD^ | clang-format-diff.py -p1 -i
+ git diff -U0 --no-color -r HEAD~1 HEAD | clang-format-diff.py -p1 -i
+
+It should be noted that the filename contained in the diff is used unmodified
+to determine the source file to update. Users calling this script directly
+should be careful to ensure that the path in the diff is correct relative to the
+current working directory.
+"""
+
+import argparse
+import difflib
+import re
+import subprocess
+import sys
+from io import StringIO
+
+
+def main():
+ parser = argparse.ArgumentParser(description=
+ 'Reformat changed lines in diff. Without -i '
+ 'option just output the diff that would be '
+ 'introduced.')
+ parser.add_argument('-i', action='store_true', default=False,
+ help='apply edits to files instead of displaying a diff')
+ parser.add_argument('-p', metavar='NUM', default=0,
+ help='strip the smallest prefix containing P slashes')
+ parser.add_argument('-regex', metavar='PATTERN', default=None,
+ help='custom pattern selecting file paths to reformat '
+ '(case sensitive, overrides -iregex)')
+ parser.add_argument('-iregex', metavar='PATTERN', default=
+ r'.*\.(cpp|cc|c\+\+|cxx|c|h|hpp|m|mm|js|ts)$',
+ help='custom pattern selecting file paths to reformat '
+ '(case insensitive, overridden by -regex)')
+ parser.add_argument('-sort-includes', action='store_true', default=False,
+ help='let clang-format sort include statements')
+ parser.add_argument('-v', '--verbose', action='store_true',
+ help='be more verbose, ineffective without -i')
+ parser.add_argument('-style',
+ help='formatting style to apply (LLVM, Google, Chromium, '
+ 'Mozilla, WebKit, file or JSON config)')
+ parser.add_argument('-binary', default='clang-format',
+ help='location of binary to use for clang-format')
+ args = parser.parse_args()
+
+ try:
+ p = int(args.p)
+ except ValueError:
+ print('error: invalid -p value')
+ return 1
+
+ if args.regex is not None:
+ file_re = re.compile(args.regex)
+ else:
+ file_re = re.compile(args.iregex, re.IGNORECASE)
+
+ changed_files = []
+ lines_by_file = {}
+ for line in sys.stdin:
+ match = re.search(r'^\+\+\+\ (.*?/){%s}(\S*)' % p, line)
+ if match:
+ filename = match.group(2)
+ if file_re.search(filename):
+ changed_files.append(filename)
+
+ match = re.search(r'^@@.*\+(\d+)(,(\d+))?', line)
+ if match:
+ start_line = int(match.group(1))
+ line_count = 1
+ if match.group(3):
+ line_count = int(match.group(3))
+ if line_count == 0:
+ continue
+ end_line = start_line + line_count - 1
+ lines_by_file.setdefault(filename, []).extend(
+ ['-lines', str(start_line) + ':' + str(end_line)])
+
+ if not changed_files:
+ return 0
+
+ # Reformat files containing changes in place.
+ for filename in changed_files:
+ if args.i and args.verbose:
+ print('Formatting', filename)
+ command = [args.binary, filename]
+ if args.i:
+ command.append('-i')
+ if args.style:
+ command.extend(['-style', args.style])
+ if args.sort_includes:
+ command.append('-sort-includes')
+ if filename in lines_by_file:
+ command.extend(lines_by_file[filename])
+ if not args.i:
+ command.append('--output-replacements-xml')
+
+ try:
+ p = subprocess.Popen(command, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ stdin=subprocess.PIPE)
+ stdout, stderr = p.communicate()
+ if p.returncode != 0:
+ print("clang-format failed with return code", p.returncode)
+ print(stderr.decode())
+ return p.returncode
+
+ if not args.i:
+ print(stdout.decode('utf-8'), end='')
+
+ except KeyboardInterrupt:
+ # Ctrl-C, print a newline so the next shell prompt is on a new line.
+ print('')
+ return 1
+
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
\ No newline at end of file